IIC匯流排協議的原始驅動程式碼與其例項應用程式碼編寫
阿新 • • 發佈:2018-12-14
原始驅動程式碼:
//備註:該驅動程式碼針對8051晶片,晶振為12MHz的IIC驅動程式 #include "intrins.h" #define somenop {_nop_();_nop_();_nop_();_nop_();_nop_();} //這裡根據時鐘大小需要適當修改_nop_();個數,比如針對stc15晶片,需要將_nop_();的個數乘上8 #define SlaveAddrW 0xA0 #define SlaveAddrR 0xA1 //匯流排引腳定義 sbit SDA = P2^1; /* 資料線 */ sbit SCL = P2^0; /* 時鐘線 */ //匯流排啟動條件 void IIC_Start(void) { SDA = 1; SCL = 1; somenop; SDA = 0; somenop; SCL = 0; } //匯流排停止條件 void IIC_Stop(void) { SDA = 0; SCL = 1; somenop; SDA = 1; } //應答位控制 void IIC_Ack(bit ackbit) { if(ackbit) { SDA = 0; } else { SDA = 1; } somenop; SCL = 1; somenop; SCL = 0; SDA = 1; somenop; } //等待應答 bit IIC_WaitAck(void) { SDA = 1; somenop; SCL = 1; somenop; if(SDA) { SCL = 0; IIC_Stop(); return 0; } else { SCL = 0; return 1; } } //通過I2C匯流排傳送資料 void IIC_SendByte(unsigned char byt) { unsigned char i; for(i=0;i<8;i++) { if(byt&0x80) { SDA = 1; } else { SDA = 0; } somenop; SCL = 1; byt <<= 1; somenop; SCL = 0; } } //從I2C總線上接收資料 unsigned char IIC_RecByte(void) { unsigned char da; unsigned char i; for(i=0;i<8;i++) { SCL = 1; somenop; da <<= 1; if(SDA) da |= 0x01; SCL = 0; somenop; } return da; }
例項應用程式碼編寫:
#include "intrins.h" #include "iic.h" #define somenop {_nop_();_nop_();_nop_();_nop_();_nop_();} //匯流排引腳定義 sbit SDA = P2^1; /* 資料線 */ sbit SCL = P2^0; /* 時鐘線 */ //匯流排開始條件 void IIC_Start(void) { SDA = 1; SCL = 1; somenop; SDA = 0; somenop; SCL = 0; } //匯流排停止條件 void IIC_Stop(void) { SDA = 0; SCL = 1; somenop; SDA = 1; } //應答位控制 void IIC_Ack(bit ackbit) { if(ackbit) { SDA = 0; } else { SDA = 1; } somenop; SCL = 1; somenop; SCL = 0; SDA = 1; somenop; } //等待應答 bit IIC_WaitAck(void) { SDA = 1; somenop; SCL = 1; somenop; if(SDA) { SCL = 0; IIC_Stop(); return 0; } else { SCL = 0; return 1; } } //通過I2C匯流排傳送資料 void IIC_SendByte(uchar byt) { unsigned char i; for(i=0;i<8;i++) { if(byt&0x80) { SDA = 1; } else { SDA = 0; } somenop; SCL = 1; byt <<= 1; somenop; SCL = 0; } } //從I2C總線上接收資料 uchar IIC_RecByte(void) { unsigned char da; unsigned char i; for(i=0;i<8;i++) { SCL = 1; somenop; da <<= 1; if(SDA) da |= 0x01; SCL = 0; somenop; } return da; } //讀寫IIC的值 uchar IIC_AD_Read(uchar add) //add為地址 { uchar temp; IIC_Start(); //啟動匯流排 IIC_SendByte(0x90); //器件的地址 IIC_WaitAck(); //等待響應 IIC_SendByte(add); //讀哪個通道的內容(add為通道地址) IIC_WaitAck(); IIC_Stop(); IIC_Start(); IIC_SendByte(0x91); //器件地址加1 IIC_WaitAck(); temp = IIC_RecByte(); IIC_Stop(); return temp; //返回temp } //讀EEPROM的值 uchar IIC_EEPROM_Read(uchar add1) //add為地址 { uchar temp1; IIC_Start(); //啟動匯流排 IIC_SendByte(0xa0); //EEPROM晶片的地址 IIC_WaitAck(); //等待響應 IIC_SendByte(add1); //讀哪個通道的內容(add為通道地址) IIC_WaitAck(); IIC_Stop(); IIC_Start(); IIC_SendByte(0xa1); IIC_WaitAck(); temp1 = IIC_RecByte(); IIC_Stop(); return temp1; //返回temp1 } //將數值寫入EEPROM void IIC_EEPROM_Write(uchar add2, uchar dat) { IIC_Start(); IIC_SendByte(0xa0); //選擇EEPROM晶片地址 IIC_WaitAck(); //等待響應 IIC_SendByte(add2); //寫地址 IIC_WaitAck(); //等待響應 IIC_SendByte(dat); //對其進行寫資料 IIC_WaitAck(); //等待響應 IIC_Stop(); //寫入成功,IIC停止 }