STM8S的硬件I2C还是存在问题,不敢贸然使用. #define SCL PE_ODR_ODR1 #define SDA PE_ODR_ODR2 #define SDAM PE_IDR_IDR2 #define SET_SCL_OUT() {PE_DDR_DDR1=1; PE_CR1_C11 = 1; PE_CR2_C21 = 0;} #define SET_SDA_OUT() {PE_DDR_DDR2=1; PE_CR1_C12 = 1; PE_CR2_C22 = 0;} #define SET_SDA_IN() {PE_DDR_DDR2=0; PE_CR1_C12 = 0; PE_CR2_C22 = 0;} //-------------------------------------------------------------- // Prototype : void I2C_Start(void) // Calls : Delay_5us() // Description : Start Singnal //-------------------------------------------------------------- void I2C_Init(void) { I2C_CR1 &= 0xFE; // PE=0, disable I2C module SET_SCL_OUT(); SET_SDA_OUT(); }
//-------------------------------------------------------------- // Prototype : void Delay_5us(void) // Description : 大约延时5us //-------------------------------------------------------------- void Delay_5us(void) { uchar i; //fcpu 8MHz 时 for (i=50; i>0; i--); }
//-------------------------------------------------------------- // Prototype : void I2C_Start(void) // Calls : Delay_5us() // Description : Start Singnal //-------------------------------------------------------------- void I2C_Start(void) { // SDA 1->0 while SCL High SDA = 1; SCL = 1; Delay_5us(); SDA = 0; Delay_5us(); SCL = 0; }
//-------------------------------------------------------------- // Prototype : void I2C_Stop(void) // Calls : Delay_5us() // Description : Stop Singnal //-------------------------------------------------------------- void I2C_Stop(void) { // SDA 0->1 while SCL High SDA = 0; SCL = 1; Delay_5us(); SDA = 1; Delay_5us(); } //-------------------------------------------------------------- // Prototype : void I2C_SendACK(uchar ack); // Calls : Delay_5us() // Parameters : bit ack:1-noack, 0-ack // Description : Master device send ACK to slave device. //-------------------------------------------------------------- void I2C_SendACK(uchar ack) { if(ack == 0) { SDA = 0; } else { SDA = 1; }
SCL = 1; Delay_5us();
SCL = 0; Delay_5us(); } //-------------------------------------------------------------- // Prototype : uchar I2C_SendByte(uchar sendDAT) // Calls : Delay_5us() // Parameters : uchar sendDAT---data to be send // Return Value : CY--slave ack (1---noack,0---ack) // Description : Send one byte to I2C //-------------------------------------------------------------- uchar I2C_SendByte(uchar sendDAT) { uchar i,revack; for (i= 0 ; i< 8; i++) { SCL = 0; Delay_5us(); if (sendDAT & 0x80) // write data { SDA = 1; } else { SDA = 0; } sendDAT <<= 1; SCL = 1; Delay_5us(); }
SCL = 0; Delay_5us();
SET_SDA_IN();
SCL = 1; asm("nop"); asm("nop");
revack = (uchar)SDAM;
Delay_5us(); SCL = 0;
SET_SDA_OUT();
Delay_5us(); return revack; }
//-------------------------------------------------------------- // Prototype : uchar I2C_RecvByte() // Calls : Delay_5us() // Parameters : none // Return Value : revDAT- received data // Description : Receive one byte from I2C //-------------------------------------------------------------- uchar I2C_RecvByte() { uchar i; uchar revDAT = 0;
SDA = 1; // latch the Data port befor reading
SET_SDA_IN();
for (i=0; i<8; i++) { revDAT <<= 1;
SCL = 1;
asm("nop"); asm("nop");
if (SDAM) { revDAT |= 0x01; } else { revDAT &= 0xfe; } Delay_5us(); SCL = 0; Delay_5us(); }
SET_SDA_OUT();
return revDAT; }
//-------------------------------------------------------------- // Prototype : void Write_PT2314(uchar wdata) // Calls : I2C_Start(), I2C_Stop(),I2C_SendByte() // Parameters : RegAddr-- target memory address, // wrdata--- data to be writing // Description : Write one byte to target memory //-------------------------------------------------------------- void Write_24c02(uchar regadd,uchar wdata) { I2C_Start(); I2C_SendByte(0xA0); // Device Addr + Write (operation) I2C_SendByte(regadd); I2C_SendByte(wdata); I2C_Stop(); } uchar Read_24c02(uchar regadd) { uchar revdata;
I2C_Start(); I2C_SendByte(0xA0); // Device Addr + Write (operation) I2C_SendByte(regadd);
I2C_Start(); I2C_SendByte(0xA1); // Device Addr + Write (operation)
revdata = I2C_RecvByte(); I2C_SendACK(1);
I2C_Stop();
return revdata; }
|