I2C是一種總線式結構,它只須要SCL時鐘信號線與SDA數據線,兩根線就能將鏈接與總線上的設備實現數據通訊,因爲它的簡便的構造設計,因而成爲一種較爲經常使用的通訊方式。css
因爲I2C採用的是主從式通訊方式,因此,通訊的過程徹底由主設備仲裁。在通訊以前,必須由主設備發送一個起始信號,決定數據是否能夠開始傳送,而且在結束通訊時,必須再由主設備發送一個結束信號,以表示通訊已經結束。微信
由於,通訊以前,主設備須要發送一個起始信號,因此,先講一下起始信號。經過上面的圖就能夠知道(上圖中的第一個波形圖是SDA數據線,第二個波形圖是SCL時鐘信號線),起始信號是在SCL時鐘信號線處於高電平時,SDA數據線由高電平轉換爲低電平,也就是產生一個降低沿,就意味着起始信號已經發送,數據的通訊能夠進行了。代碼以下:
ide
void I2C_Start() { I2C_SDA = 1; I2C_Delay10us(); I2C_SCL = 1; I2C_Delay10us();//創建時間是I2C_SDA保持時間>4.7us I2C_SDA = 0; I2C_Delay10us();//保持時間是>4us I2C_SCL = 0; I2C_Delay10us(); }
一樣的,由上圖可知:結束信號,就是在SCL時鐘信號線處於高電平時,SDA數據線由低電平變爲高電平 ,也就是,SDA數據線產生一個 上升沿。代碼以下:
編碼
void I2C_Stop() { I2C_SDA = 0; I2C_Delay10us(); I2C_SCL = 1; I2C_Delay10us();//創建時間大於4.7us I2C_SDA = 1; I2C_Delay10us(); }
接下來就是該講一下,I2C數據的發送問題了。因爲I2C是主從式通訊,也就意味着一根總線上能夠掛載多個從設備,那麼主設備如何區分這些從設備呢?主設備如何知道是在與哪個從設備在通訊呢?答案是:經過地址。每個從設備都有本身的地址編碼,也就是說,主設備在與具體的某一個從設備通訊以前,必須先發送地址,以表示與主設備通訊的是該設備。從上圖可知,主設備在發送完起始信號後,馬上開始了發送從設備的地址。那麼如何發送數據地址呢?首先,在SCL時鐘信號線處於低電平時,SDA數據線上的地址信息要開始準備了。I2C通訊一個必須注意的點就是,在傳送地址信息時,都是從高位開始傳送,
spa
I2C_SDA = dat >> 7; dat = dat << 1;
接着,SCL時鐘信號線開始由低電平向高電平轉換,這個時候,SDA數據線上的數據開始在傳送了,當SCL時鐘信號線上的信號再由高電平轉換位低電平的時候,一個Bit位的數據已經傳送完畢。在地址信息傳送完畢以後,還會有一個應答信號,由於,爲了確保從設備接收到已經發送的數據,從設備就會向主設備發送一個應答信號,若主設備接收到應答信號則說明數據傳送成功,不然數據傳送失敗。很重要的一點是,總線一直是由主設備控制,那麼當從設備想要向主設備發送一個應答信號時,主設備須要是釋放總線,將總線權限交給從設備。
設計
因此,從設備在向主設備發送應答信號時,主設備應該釋放總線,代碼以下:3d
I2C_SDA = 1;
接着,由上圖可知,當SCL時鐘信號線再次拉高時,就進入了第9個時鐘週期,也就是此時開始傳送應答信號。當成功應答時,返回1,不然返回0。完整代碼以下:
blog
I2C_SDA = 1; I2C_Delay10us(); I2C_SCL = 1; while(I2C_SDA && (ack == 1)) { b++; if(b > 200) { I2C_SCL = 0; I2C_Delay10us(); return 0; } } I2C_SCL = 0; I2C_Delay10us(); return 1; }
最後,就是I2C設備(也就是主設備)數據的接收。此時,從設備發送數據給主設備,也就是,主設備進行數據的接收。那麼,主設備一樣要釋放總線權限。也就是教程
I2C_SDA = 1;
首先,SCL時鐘信號線爲低電平,這時,SDA數據線要準備好數據了,接着,SCL時鐘信號線由低電平變爲高電平,此時,數據傳送開始了,當SCL時鐘信號線再次變爲低電平是,一個Bit的數據傳送結束。代碼以下:
支付寶
uchar I2C_ReadByte() { uchar a = 0,dat = 0; I2C_SDA = 1; I2C_Delay10us(); //I2C_SCL = 0; for(a=0; a<8; a++) { I2C_SCL = 1; I2C_Delay10us(); dat <<= 1; dat |= I2C_SDA; I2C_Delay10us(); I2C_SCL = 0; I2C_Delay10us(); } return dat; }
I2C的低層時序到這裏基本上就已經結束了。
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
歡迎打賞,哈哈~
1毛兩毛也表示萬分感謝,哈哈!
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 順便附上個人微信碼,哈哈!
必定是我膨脹了,居然想要打賞!
這些教程說實話都挺好的,感興趣的大佬能夠用個人二維碼購買,感謝!