一、 IIC總線有兩根雙向信號線,一根是數據線SDA,一根是時鍾線SCL
每根接到IIC總線上的器件都有唯一的地址
二、 IIC通信協議的函數寫法
1、 起始信號
2、 終止信號
3、 寫數據
4、 讀數據
5、 發送應答信號
6、 發送非應答信號
7、 等待應答
8、 檢測IIC總線設備
三、 函數解析
1、 起始信號和終止信號
SCL為高電平期間,SDA線由高電平向低電平變化表示起始信號
SCL為高電平期間,SDA線由低電平向高電平變化表示終止信號
void i2c_Start(void) { /* 當SCL高電平時,SDA出現一個下跳沿表示I2C總線啟動信號 */ SDA = 1; SCL = 1; i2c_Delay(); SDA = 0; i2c_Delay(); SCL = 0; i2c_Delay(); } void i2c_Stop(void) { /* 當SCL高電平時,SDA出現一個上跳沿表示I2C總線停止信號 */ SDA = 0; SCL = 1; i2c_Delay(); SDA = 1; i2c_Delay(); }
2、 應答和非應答
IIC總線規定,每傳送一字節的數據后都要有一個應答信號以確定數據傳送是否被對方接收。
應答信號由接收設備產生,在SCL為高電平期間,接收設備將SDA拉低為低電平,表示數據傳輸正確,產生應答。
unsigned char i2c_WaitAck(void) { unsigned char re; //應答信號等於0則應答正確,等於1則沒有應答 SDA = 1; //釋放總線,能讓對方拉低 i2c_Delay(); SCL = 1; //此時刻開始,數據保持應答狀態穩定 i2c_Delay(); re = SDA; //0表示應答,1表示沒有應答 i2c_Delay(); SCL = 0; i2c_Delay(); return re; }
3、 IIC數據的傳送
數據位的有效性規定:IIC總線進行數據傳送時,時鍾信號為高電平期間,數據線上的數據必須保持穩定,只有在時鍾線上的信號為低電平時期,數據線上的高電平或低電平狀態才允許變化。
void i2c_SendByte(unsigned char _ucByte) { unsigned char i; //其實信號開始后SCL是被拉低的 for(i = 0; i < 8; i++) { if((_ucByte<<i) & 0x80) SDA = 1; else SDA = 0; SCL = 1; i2c_Delay(); SCL = 0; //SCL等於0的時候寫數據 if(i == 7) //最后一次時釋放總線 { SDA = 1; } i2c_Delay(); } } unsigned char i2c_ReadByte(void) { unsigned char i; unsigned char value = 0; for(i = 0; i < 8; i++) { value<<=1; //循環左移, SCL = 1; //穩定狀態的時候讀數據 if(SDA == 1) value |= 0x01;//value++; //最低位置0 else value &= 0xfe; //最低位置0 SCL = 0; //允許數據變化 i2c_Delay(); } return value; }
4、產生一個應答信號和一個非應答信號
/* ********************************************************************************************************* * 函 數 名: i2c_Ack * 功能說明: CPU產生一個ACK信號 * 形 參: 無 * 返 回 值: 無 ********************************************************************************************************* */ void i2c_Ack(void) { SDA = 0;//響應 i2c_Delay(); SCL = 1; i2c_Delay(); SCL = 0; i2c_Delay(); //在SCL為高電平期間SDA都為0即產生一個應答信號 SDA = 1; //釋放總線 i2c_Delay(); } /* ********************************************************************************************************* * 函 數 名: i2c_NAck * 功能說明: CPU產生1個NACK信號 * 形 參: 無 * 返 回 值: 無 ********************************************************************************************************* */ void i2c_NAck(void) { SDA = 1; i2c_Delay(); SCL = 1; i2c_Delay(); SCL = 0; i2c_Delay(); //在SCL為高電平期間SDA都為1即產生一個非應答信號 }
5、延時函數
/* ********************************************************************************************************* * 函 數 名: i2c_Delay * 功能說明: I2C總線位延遲,最快400KHz * 形 參: 無 * 返 回 值: 無 ********************************************************************************************************* */ static void i2c_Delay(void) { unsigned char i; /* 實際應用選擇小於400KHz左右的速率即可 */ for (i = 0; i < 10; i++); }