i2c 協議解析
1、基本概念
主機 初始化傳送,產生時鐘訊號和終止傳送的器件
從機 被主機定址的器件
傳送器 傳送資料到匯流排的器件
接收器 從匯流排接收資料的器件
多主機 同時有多於一個主機嘗試控制匯流排 但不破壞報文
仲裁 是一個在有多個主機同時嘗試控制匯流排,但只允許其中一個控制匯流排並使報文不被破壞的過程
同步 兩個或多個器件同步時鐘訊號的過程
2、硬體結構
每一個I2C匯流排器件內部的SDA、SCL引腳電路結構都是一樣的,引腳的輸出驅動與輸入緩衝連在一起。其中輸出為漏極開路的場效電晶體、輸入緩衝為一隻高輸入阻抗的同相器。這種電路具有兩個特點:
(1)由於 SDA、SCL 為漏極開路結構,藉助於外部的上拉電阻實現了訊號的“線與”邏輯;
(2)引腳在輸出訊號的同時還將引腳上的電平進行檢測,檢測是否與剛才輸出一致。為 “時鐘同步”和“匯流排仲裁”提供硬體基礎。
3、時鐘同步
如果從機希望主機降低傳送速度可以通過將SCL主動拉低延長其低電平時間的方法來通知主機,當主機在準備下一次傳送發現SCL的電平被拉低時就進行等待,直至從機完成操作並釋放SCL線的控制控制權。這樣以來,主機實際上受到從機的時鐘同步控制。可見SCL線上的低電平是由時鐘低電平最長的器件決定;高電平的時間由高電平時間最短的器件決定。這就是時鐘同步,它解決了I2C匯流排的速度同步問題。
4、主機發送資料流程
(1)主機在檢測到匯流排為“空閒狀態”(即 SDA、SCL 線均為高電平)時,傳送一個啟動訊號“S”,開始一次通訊的開始
(2)主機接著傳送一個命令位元組。該位元組由 7 位的外圍器件地址和 1 位讀寫控制位 R/W組成(此時 R/W=0)
(3)相對應的從機收到命令位元組後向主機回饋應答訊號 ACK(ACK=0)
(4)主機收到從機的應答訊號後開始傳送第一個位元組的資料
(5)從機收到資料後返回一個應答訊號 ACK
(6)主機收到應答訊號後再發送下一個資料位元組
(7)當主機發送最後一個數據位元組並收到從機的 ACK 後,通過向從機發送一個停止訊號P結束本次通訊並釋放匯流排。從機收到P訊號後也退出與主機之間的通訊
注意:①主機通過傳送地址碼與對應的從機建立了通訊關係,而掛接在總線上的其它從機雖然同時也收到了地址碼,但因為與其自身的地址不相符合,因此提前退出與主機的通訊;②主機的一次傳送通訊,其傳送的資料數量不受限制。主機是通過 P 訊號通知傳送的結束,從機收到 P 訊號後退出本次通訊;③主機的每一次傳送後都是通過從機的 ACK 訊號瞭解從機的接收狀況,如果應答錯誤則重發。
5、主機接收資料流程
(1)主機發送啟動訊號後,接著傳送命令位元組(其中 R/W=1)
(2)對應的從機收到地址位元組後,返回一個應答訊號並向主機發送資料
(3)主機收到資料後向從機反饋一個應答訊號
(4)從機收到應答訊號後再向主機發送下一個資料
(5)當主機完成接收資料後,向從機發送一個“非應答訊號(ACK=1)”,從機收到ASK=1 的非應答訊號後便停止傳送
(6)主機發送非應答訊號後,再發送一個停止訊號,釋放匯流排結束通訊
注意:主機所接收資料的數量是由主機自身決定,當傳送“非應答訊號/A”時從機便結束傳送並釋放匯流排(非應答訊號的兩個作用:前一個數據接收成功,停止從機的再次傳送)。
6、匯流排死鎖原因分析
I2C匯流排寫操作過程中,主機在產生啟動訊號後控制SCL產生8個時鐘脈衝,然後拉低SCL訊號為低電平,在這個時候,從機輸出應答訊號,將SDA訊號拉為低電平。如果這個時候主機異常復位,SCL就會被釋放為高電平。此時,如果從機沒有復位,就會繼續I2C的應答,將SDA一直拉為低電平,直到SCL變為低電平,才會結束應答訊號。而對於主機來說,復位後檢測SCL和SDA訊號,如果發現SDA訊號為低電平,則會認為I2C匯流排被佔用,會一直等待SCL和SDA訊號變為高電平。這樣,主機等待從機釋放SDA訊號,而同時從機又在等待主機將SCL訊號拉低以釋放應答訊號,兩者相互等待,I2C匯流排進人一種死鎖狀態。同樣,當I2C進行讀操作時,從機應答後輸出資料,如果在這個時刻主機異常復位而此時從機輸出的資料位正好為0,也會導致I2C匯流排進入死鎖狀態。
解決方案通常有如下幾種:
(1)將從機的電源設計為可控,當發生匯流排死鎖的時將從機復位
(2)可以在從機的程式中加入監測功能,如果匯流排長時間被拉低則釋放對匯流排的控制
(3)在主機中增加I2C匯流排恢復程式。每次主機復位後,如果檢測到SDA被拉低,則控制SCL產生<=9個時鐘脈衝(針對8位資料的情況),每傳送一個時鐘脈衝就檢測SDA是否被釋放,如果SDA已經被釋放就再模擬產生一個停止訊號,這樣從機就可以完成被掛起的讀寫操作,從死鎖狀態中恢復過來。這種方法有一定的侷限性,因為大部分主機的I2C模組由內建的硬體電路來實現,軟體並不能夠直接控制SCL訊號模擬產生需要時鐘脈衝
7、處理器的I2C模組會在如下所述的情況產生中斷訊號
RX_UNDER 當處理器通過IC_DATA_CMD暫存器讀取接收緩衝器為空時置位
RX_OVER 當接收緩衝器被填滿,而且還有資料從外設傳送過來時被置位;緩衝器被填滿後接收的資料將會丟失
RX_FULL 當接收緩衝器達到或者超過IC_RX_TL暫存器中規定的閾值時被置位;當資料低於閾值時標誌位將被自動清除
TX_OVER 當傳送緩衝器被填滿,而且處理器試圖傳送另外的命令寫IC_DATA_CMD暫存器時被置位
TX_EMPTY 當傳送緩衝器等於或者低於IC_TX_TL暫存器中規定的閾值時被置位;當資料高於閾值時標誌位將被自動清除
RD_REQ 當i2c模組作為從機時並且另外的主機試圖從本模組讀取資料時被置位
TX_ABRT 當i2c模組無法完成處理器下達的命令時被置位,有如下幾種原因:
* 傳送地址位元組後沒有從機應答
* 地址識別成功後主機發送的資料從機沒有應答
* 當i2c模組只能作為從機時試圖傳送主機命令
* 當模組的RESTART功能被關閉,而處理試圖完成的功能必須要RESTART功能開啟才能完成
* 高速模組主機程式碼被應答
* START BYTE被應答
* 模組仲裁失敗
無論標誌位什麼時候被置位,傳送緩衝器和接收緩衝器的內容都會被重新整理
RX_DONE 當i2c模組作為從機發送資料時,如果主機沒有應答則置位;這種情況發生在i2c模組傳送最後一個位元組資料時,表明傳輸結束
ACTIVITY 表明i2c模組正在活動,這個標誌位將會一直保持直到用以下4種方式清除:
* 關閉i2c
* 讀取IC_CLR_ACTIVITY暫存器
* 讀取IC_CLR_INTR暫存器
* 系統重啟
即使i2c模組是空閒的,這個標誌仍然需要被置位直到被清除,因為這表明i2c總線上有資料正在傳輸
STOP_DET 表明i2c總線上產生了STOP訊號,無論模組作為主機還是從機
START_DET 表明i2c總線上產生了START訊號,無論模組作為主機還是從機