I2C通信基本原理以及使用C語言實現


  I2C總線是一種簡單、雙向二線制同步串行總線。它只需要兩根線即SCL(時鍾信號線)和SDA(數據線),就可在連接於總線上的器件之間傳送信息。

  I2C采用的是主從式通信方式,通信的過程完全由主設備決定。通訊的起始信號和終止信號都由主設備發送。

 

 

起始信號:在SCL時鍾信號在高電平期間,SDA信號產生一個下降沿,起始之后SDA和SCL都為0。

 1 void I2C_Start()
 2 {
 3     I2C_SDA = 1;
 4     I2C_Delay10us();
 5     I2C_SCL = 1;
 6     I2C_Delay10us(); //建立時間是I2C_SDA保持時間>4.7us
 7 
 8     I2C_SDA = 0;  //保持時間是>4us
 9     I2C_Delay10us();
10     I2C_SCL = 0;
11     I2C_Delay10us();
12 }

 

 終止信號:在SCL時鍾信號在高電平期間,SDA信號產生一個上升沿,終止后保持SDA和SCL都為1,表示總線空閑。

 1 void I2C_Stop()
 2 {
 3     I2C_SDA = 0;
 4     I2C_Delay10us();
 5     I2C_SCL = 1;
 6     I2C_Delay10us(); //建立時間是I2C_SDA保持時間>4.7us
 7 
 8     I2C_SDA = 1;
 9     I2C_Delay10us();
10 }

 

I2C總線上可以掛多個從設備,為了區分從設備,每個設備都有自己的地址編碼。當主從通訊時,主設備必須先發送一個從設備的地址。在SCL時鍾信號線處於低電平時,SDA數據線上的地址信息要開始准備了。I2C在傳送地址信息時都是從高位開始傳送。

 SCL時鍾信號低電平轉換為高電平再轉換為低電平,一個bit的數據傳送完畢。如果數據傳送成功,從設備將會返回一個應答信號,此時,總線應該要處於空閑狀態,等待應答信號。

 1 uchar I2C_SendByte(uchar dat, uchar ack)
 2 {
 3     uchar a = 0, b = 0;//最大255,一個機器周期1us 最大延時255us
 4 
 5     for(a=0; a<8; a++)
 6     {
 7         I2C_SDA = dat >> 7;
 8         dat = dat << 1;
 9         I2C_Delay10us();
10         I2C_SCL = 1;
11         I2C_Delay10us();//建立時間>4.7us
12         I2C_SCL = 0;
13         I2C_Delay10us();//建立時間>4us
14     }
15 
16     I2C_SDA = 1;
17     I2C_Delay10us();
18     I2C_SCL = 1;
19     I2C_Delay10us();
20 
21     while(I2C_SDA && (ack == 1)) // 等待應答,也就是等待從設備把I2C_SDA拉低
22     {
23         b++;
24         if(b > 200)
25         {
26             I2C_SCL = 0;
27             I2C_Delay10us();
28             return 0;
29         }
30     }
31 
32     I2C_SCL = 0;
33     I2C_Delay10us();
34     return 1;
35 }

 

當從設備需要讀取從設備數據時,總線同樣需要處於空閑狀態。當SCL低電平轉換為高電平時,讀取一個bit的數據,SCL再次轉換為低電平時,讀取結束。數據從高位開始讀取。

 1 uchar I2C_ReadByte()
 2 {
 3     uchar a = 0, dat = 0;
 4     I2C_SDA = 1;  //起始和發送一個字節之后I2C_SCL都是0
 5     I2C_Delay10us();
 6     for(a=0; a<8; a++)
 7     {
 8         I2C_SCL = 1;
 9         I2C_Delay10us();
10         dat <<= 1;
11         dat |= I2C_SDA;
12         I2C_Delay10us();
13         I2C_SCL = 0;
14         I2C_Delay10us();
15     }
16     return dat;
17 
18 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM