STM8S的硬件I2C还是存在问题,不敢贸然使用.
于是决定用模拟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 时 ; i>; i--); } //-------------------------------------------------------------- // Prototype : void I2C_Start(void) // Calls : Delay_5us() // Description : Start Singnal //-------------------------------------------------------------- void I2C_Start(void) { // SDA 1->0 while SCL High SDA = ; SCL = ; Delay_5us(); SDA = ; Delay_5us(); SCL = ; } //-------------------------------------------------------------- // Prototype : void I2C_Stop(void) // Calls : Delay_5us() // Description : Stop Singnal //-------------------------------------------------------------- void I2C_Stop(void) { // SDA 0->1 while SCL High SDA = ; SCL = ; Delay_5us(); SDA = ; 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) { ) { SDA = ; } else { SDA = ; } SCL = ; Delay_5us(); SCL = ; 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; ; i< ; i++) { SCL = ; Delay_5us(); if (sendDAT & 0x80) // write data { SDA = ; } else { SDA = ; } sendDAT <<= ; SCL = ; Delay_5us(); } SCL = ; Delay_5us(); SET_SDA_IN(); SCL = ; asm("nop"); asm("nop"); revack = (uchar)SDAM; Delay_5us(); SCL = ; 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 = ; SDA = ; // latch the Data port befor reading SET_SDA_IN(); ; i<; i++) { revDAT <<= ; SCL = ; asm("nop"); asm("nop"); if (SDAM) { revDAT |= 0x01; } else { revDAT &= 0xfe; } Delay_5us(); SCL = ; 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(); I2C_Stop(); return revdata; }