標籤:nbsp 非同步 高電平 info lips 使用者 進位 部分 log
IIC協議解釋
推薦資源: http://m.elecfans.com/article/574049.html and 51921129 (動態圖講解)
(1)概述
I2C(Inter-Integrated Circuit BUS) 整合電路匯流排,該匯流排由NXP(原PHILIPS)公司設計,多用於主控制器和從器件間的主從通訊,在小資料量場合使用,傳輸距離短,任意時刻只能有一個主機等特性。
經常IIC和SPI介面被認為指定是一種硬體裝置,但其實這樣的說法是不盡準確的,嚴格的說他們都是人們所定義的軟硬結合體,分為物理層(四線結構)和協議層(主機,從機,時鐘極性,時鐘相位)。
IIC,SPI的區別不僅在與物理層,IIC比SPI有著一套更為複雜的協議層定義。下面來分別說明一下IIC的物理層和協議層。
(2)IIC的物理層
a.只要求兩條匯流排線路,一條是串列資料線SDA,一條是串列時鐘線SCL。(IIC是半雙工,而不是全雙工系統)。
b.每個串連到匯流排的器件都可以通過唯一的地址和其它器件通訊,主機/從機角色和地址可配置,主機可以作為主機發送器和主機接收器。
c.IIC是真正的多主機匯流排,(而這個SPI在每次通訊前都需要把主機定死,而IIC可以在通訊過程中,改變主機),如果兩個或更多的主機同時請求匯流排,可以通過衝突檢測和仲裁防止匯流排資料被破壞。
d.傳輸速率在標準模式下可以達到100kb/s,快速模式下可以達到400kb/s。
e.串連到匯流排的IC數量只是受到匯流排的最大負載電容400pf限制。
一個典型的IIC介面如(1)所示
圖(1)
(3)IIC的協議層
IIC的協議層才是掌握IIC的關鍵。現在簡單概括如下:
a.資料的有效性
在時鐘的高電平周期內,SDA線上的資料必須保持穩定,資料線僅可以在時鐘SCL為低電平時改變。除非作為起始/結束條件。
(2)所示:
圖(2)
b.起始和結束條件
起始條件:當SCL為高電平的時候,SDA線上由高到低的跳變被定義為起始條件,結束條件:當SCL為高電平的時候,SDA線上由低到高的跳變被定義為停止條件,要注意起始和終止訊號都是由主機發出的,串連到I2C匯流排上的器件,若具有I2C匯流排的硬體介面,則很容易檢測到起始和終止訊號。匯流排在起始條件之後,視為忙狀態,在停止條件之後被視為空白閑狀態,對起始條件和結束條件的描述如(3)所示。
圖(3)
c.應答
每當主機向從機發送完一個位元組的資料,主機總是需要等待從機給出一個應答訊號,以確認從機是否成功接收到了資料,從機應答主機所需要的時鐘仍是主機提供的,應答出現在每一次主機完成8個資料位元傳輸後緊跟著的刻度,低電平0表示應答,1表示非應答,(4)所示。
圖(4)
d.資料框架格式
I2C匯流排上傳送的資料訊號是廣義的,既包括地址訊號,又包括真正的資料訊號。
在起始訊號後必須傳送一個從機的地址(7位),第8位是資料的傳送方向位(R/T),用“0”表示主機發送資料(T),“1”表示主機接收資料(R)。{這裡小編在驅動MPU6050模組的時候,就犯過這樣的錯誤,它寫的MPU6050從機地址是0x68,因為發送從機地址的時候,要加一位讀寫方向位,因為剛開始應該是向這個MPU6050裡寫從機裡某個寄存器的地址,所以應該是7位地址 0x68(1101000)+二進位位0=11010000)也就是0xD0,表示要向該IIC裝置裡寫東西,然後再緊接著寫入IIC裝置裡的寄存器地址,而我直接寫入了0x68,導致出錯},
每次資料傳送總是由主機產生的終止訊號來結束。但是,若主機希望繼續佔用匯流排進行新的資料傳送,則可以不產生終止訊號,馬上再次發出起始訊號對另一從機進行定址。在匯流排的一次資料轉送過程中,可以有以下幾種組合方式:
[1] 主機向從機發送資料,資料傳送方向在整個傳送過程中不變:(寫入模式)
註:有陰影部分表示資料由主機向從機傳送,無陰影部分則表示
資料由從機向主機傳送。
A
表示應答(低電平),
A
非表示非應答(高電平)。
S
表示起始訊號,
P
表示終止訊號。
[2]主機在第一個位元組後,立即從從機讀資料:(讀模式)
[3]在傳送過程中,當需要改變傳送方向時,起始訊號和從機地址都被重複產生一次,但兩次讀/寫方向位正好反相:(讀寫切換模式)
注釋: 讀模式的結束時,不需要進應答。
一般情況下,[3]是比較常見的,比如MPU6050模組:發送起始訊號等待從機應答(?需要麼,查看下MPU6050 manual)寫一個從機地址+0(表示寫),等待從機應答發送一個位元組的MPU6050加速度儲存寄存器地址,等待從機應答再發送一次起始訊號等待從機應答寫一個從機地址+1(表示讀)等待從機應答讀取MPU6050感應器資料主機非應答
e.IIC訊號的類比主機可以採用不帶I2C匯流排介面的單片機,如80C51、AT89C2051等單片機,利用軟體實現I2C匯流排的資料傳送,即軟體與硬體結合的訊號類比。即使是含有IIC硬體的單片機(如stm32 103系列)也有一定的缺陷,所以一般也會類比IIC的時序。現將具體時間如下:
IIC時鐘頻率:不高於400K
應答:當IIC主機(不一定是發送端還是接受端)將8位元據或命令傳出後,會將SDA訊號設定為輸入,等待從機應答(等待SDA由高電平拉為低電平)
若從機正確應答,表明資料或者命令傳輸成功,否則傳輸失敗,注意,應答訊號是資料接收方發送給資料發送方的。
IIC器件地址:每一個IIC器件都有一個器件地址,有的器件地址在出廠時地址就設定好了,使用者不可以更改,比如OV7670的
地址為0x42。有的器件例如EEPROM,前四個地址已經確定為1010,後三個地址是由硬體連結確定的,所以一
個IIC匯流排最多能連8個EEPROM晶片。
圖上開始訊號之後,七位地址代表器件地址,第八位代表讀或者寫(0為寫,1代表讀),然後跟著響應位。
IIC器件單位元組寫時序:
IIC器件多位元組地址寫時序:多位元組地址比單位元組地址在時序上就多了一塊寫地址
單位元組器件讀時序:注意最後產生無應答訊號,另外多位元組地址讀時序跟單位元組類似,只不過是多了幾個地址位元組而已。
三大串列匯流排:uart、spi、iic
同步:spi 非同步 :iic,uart
同步和非同步區別:採集資料是否用的是時鐘的沿,如果是時鐘沿采資料,同步傳輸,如果電平採集資料是非同步
串口接受資料其實就是一個串轉並的過程
具體的程式碼如下:
//產生起始訊號void I2C_Start(void){ I2C_SDA_OUT();//配置一下引腳,引腳設定為輸出 I2C_SDA_H;//把資料線拉高 I2C_SCL_H;//把時鐘線拉高 delay_us(5);//延時5微秒,要求大於4.7微秒 I2C_SDA_L; //拉低,產生下降沿 delay_us(6);//這個過程大於4微秒 I2C_SCL_L;//最後一定要把這個時鐘線拉低,因為只有時鐘線拉低的時候才允許資料 變化。}//產生停止訊號void I2C_Stop(void){ I2C_SDA_OUT(); I2C_SCL_L; I2C_SDA_L; I2C_SCL_H; delay_us(6); I2C_SDA_H; delay_us(6);}//主機產生應答訊號ACKvoid I2C_Ack(void){ I2C_SCL_L; I2C_SDA_OUT(); I2C_SDA_L; delay_us(2); I2C_SCL_H; delay_us(5); I2C_SCL_L;} //主機不產生應答訊號NACKvoid I2C_NAck(void){ I2C_SCL_L; I2C_SDA_OUT(); I2C_SDA_H; delay_us(2); I2C_SCL_H; delay_us(5); I2C_SCL_L;}//等待從機應答訊號,我們只負責主機應答訊號的產生,從機應答訊號//我們不控制。//傳回值:1 接收應答失敗// 0 接收應答成功u8 I2C_Wait_Ack(void){ u8 tempTime=0; I2C_SDA_IN(); //配置為上拉輸入。 I2C_SDA_H; //主機釋放資料匯流排,等待從機產生應答訊號 delay_us(1); I2C_SCL_H; delay_us(1); //等待從機對資料匯流排的操作。低電平代表應答 while(GPIO_ReadInputDataBit(GPIO_I2C,I2C_SDA)) { tempTime++; //這個屬於軟體延時,不一定準確。 if(tempTime>250) //如果時間逾時,沒有應答就停止。 { I2C_Stop(); return 1; //沒有響應的話返回1. } } I2C_SCL_L; return 0; //如果有響應的話就返回0.} 針對於不同的IIC裝置,IIC協議可能會有一定的區別,有的地址需要左移一位,把最低位騰出來做讀寫位。 參考: https://www.cnblogs.com/zhangjiansheng/p/7738390.htmlhttps://www.cnblogs.com/bixiaopengblog/p/7469536.html
IIC協議解釋(轉)