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信號,無論模塊作爲主機還是從機

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章