#include "mlx90614.h" #define ACK 0 #define NACK 1 #define SA 0x00 #define RAM_ACCESS 0x00 #define EEPROM_ACCESS 0x20 #define RAM_TOBJ1 0x07 #define SMBUS_PORT GPIOB #define SMBUS_SCK GPIO_Pin_10 #define SMBUS_SDA GPIO_Pin_11 #define RCC_APB2Periph_SMBUS_PORT RCC_APB2Periph_GPIOB #define SMBUS_SCK_H() SMBUS_PORT->BSRR = SMBUS_SCK #define SMBUS_SCK_L() SMBUS_PORT->BRR = SMBUS_SCK #define SMBUS_SDA_H() SMBUS_PORT->BSRR = SMBUS_SDA #define SMBUS_SDA_L() SMBUS_PORT->BRR = SMBUS_SDA #define SMBUS_SDA_PIN() SMBUS_PORT->IDR & SMBUS_SDA //?????? void SMBus_StartBit(void) { SMBUS_SDA_H(); // Set SDA line SMBus_Delay(5); // Wait a few microseconds SMBUS_SCK_H(); // Set SCL line SMBus_Delay(5); // Generate bus free time between Stop SMBUS_SDA_L(); // Clear SDA line SMBus_Delay(5); // Hold time after (Repeated) Start SMBUS_SCK_L(); // Clear SCL line SMBus_Delay(5); // Wait a few microseconds } /******************************************************************************* * Function Name : SMBus_StopBit * Description : Generate STOP condition on SMBus * Input : None * Output : None * Return : None *******************************************************************************/ void SMBus_StopBit(void) { SMBUS_SCK_L(); // Clear SCL line SMBus_Delay(5); // Wait a few microseconds SMBUS_SDA_L(); // Clear SDA line SMBus_Delay(5); // Wait a few microseconds SMBUS_SCK_H(); // Set SCL line SMBus_Delay(5); // Stop condition setup time(Tsu:sto=4.0us min) SMBUS_SDA_H(); // Set SDA line?SCK=1?,???SDA?0?1??????(???) } u8 SMBus_SendByte(u8 Tx_buffer) { u8 Bit_counter; u8 Ack_bit; u8 bit_out; for(Bit_counter=8; Bit_counter; Bit_counter--) { if (Tx_buffer&0x80) { bit_out=1; // If the current bit of Tx_buffer is 1 set bit_out } else { bit_out=0; // else clear bit_out } SMBus_SendBit(bit_out); // Send the current bit on SDA Tx_buffer<<=1; // Get next bit for checking } Ack_bit=SMBus_ReceiveBit(); // Get acknowledgment bit return Ack_bit; } void SMBus_SendBit(u8 bit_out) { if(bit_out==0) { SMBUS_SDA_L(); } else { SMBUS_SDA_H(); } SMBus_Delay(2); // Tsu:dat = 250ns minimum SMBUS_SCK_H(); // Set SCL line SMBus_Delay(6); // High Level of Clock Pulse SMBUS_SCK_L(); // Clear SCL line SMBus_Delay(3); // Low Level of Clock Pulse // SMBUS_SDA_H(); // Master release SDA line , return; } u8 SMBus_ReceiveBit(void) { u8 Ack_bit; SMBUS_SDA_H(); //?????????,???? SMBus_Delay(2); // High Level of Clock Pulse SMBUS_SCK_H(); // Set SCL line SMBus_Delay(5); // High Level of Clock Pulse if (SMBUS_SDA_PIN()) { Ack_bit=1; } else { Ack_bit=0; } SMBUS_SCK_L(); // Clear SCL line SMBus_Delay(3); // Low Level of Clock Pulse return Ack_bit; } u8 SMBus_ReceiveByte(u8 ack_nack) { u8 RX_buffer; u8 Bit_Counter; for(Bit_Counter=8; Bit_Counter; Bit_Counter--) { if(SMBus_ReceiveBit()) // Get a bit from the SDA line { RX_buffer <<= 1; // If the bit is HIGH save 1 in RX_buffer RX_buffer |=0x01; } else { RX_buffer <<= 1; // If the bit is LOW save 0 in RX_buffer RX_buffer &=0xfe; } } SMBus_SendBit(ack_nack); // Sends acknowledgment bit return RX_buffer; } void SMBus_Delay(u16 time) { u16 i, j; for (i=0; i<4; i++) { for (j=0; j>j))==0 && i>0) { BitPosition--; if(j<7) { j++; } else { j=0x00; i--; } }/*End of while */ /*Get shift value for pattern value*/ shift=BitPosition-8; /*Shift pattern value */ while(shift) { for(i=5; i<0xFF; i--) { if((crc[i-1]&0x80) && (i>0)) { temp=1; } else { temp=0; } crc[i]<<=1; crc[i]+=temp; }/*End of for*/ shift--; }/*End of while*/ /*Exclusive OR between pec and crc*/ for(i=0; i<=5; i++) { pec[i] ^=crc[i]; }/*End of for*/ } while(BitPosition>8); /*End of do-while*/ return pec[0]; } float SMBus_ReadTemp(void) { float temp; temp = SMBus_ReadMemory(SA, RAM_ACCESS|RAM_TOBJ1)*0.02-273.15; return temp; }