I2C之知(三)--I2C總線的字節格式、時鐘同步和仲裁
發送到SDA線上的每個字節必須是8位.每次傳輸的字節數量是不受限制的.每個字節后必須跟著一個ACK應答位.數據從最高有效位(MSB)開始傳輸.如果從機要執行一些功能后才能接收或者發送新的完整數據,比如說服務一個內部中斷,那么它可以將時鐘線SCL拉低來強制使主機進入wait狀態.當從機準備好新的字節數據傳輸時,釋放時鐘線SCL,數據傳輸便繼續進行.

ACK和NACK
每個字節后都有ACK發生.ACK應答位允許接收器通知發送器字節成功接收了下一個字節可以發送了.主機產生所有的時鐘脈沖,包括應答位的第9個時鐘脈沖.
ACK應答信號是如下定義的:在ACK的第9個時鐘脈沖中發送器釋放SDA線,所以接收器可以將SDA拉低,使得在這個時鐘脈沖的高電平期間保證SDA是低電平.建立和保持時間也應該計算在內.
當在第9個時鐘脈沖期間SDA仍然是高,這時定義為NACK信號.這時主機可以產生一個終止條件來終止傳輸,或者一個重復的開始條件來開始一個新的傳輸.這里有5中情況導致NACK的產生:
1.總線當前的傳輸地址上沒有接收器,所以沒有設備用ACK來響應.
2.因為接收者正在處理一些實時的功能,尚未準備與主機的通信,所以接收者不能收發.
3.在傳輸期間,接收者收到不能識別的數據或者命令.
4.在傳輸期間,接收者無法接收更多的數據字節.
5.主-接收器要通知從-發送器傳輸的結束.
時鐘同步
在空閑總線上兩個主機可以同時開始傳輸,所以必須要有一個方法來決定哪個主機來控制總線并完成其數據傳輸.這個方法就是時鐘同步和仲裁.在單主機系統中,時鐘同步和仲裁不需要了.
時鐘同步通過使用I2C接口與SCL線的線與連接實現.意味著SCL線從高到低期間會引起主機開始計算它的低電平周期,一旦主機時鐘變低,它會保持SCL線處于這種狀態直到時鐘到達高電平.然而,如果另一個時鐘依舊是低電平,時鐘的從低到高的變化并不會改變SCL線的狀態.SCL拉低的時間由最長的低電平周期決定.短一些的低電平周期的主機在這時進入HIGH wait-state.

當所有的主機的低電平周期都結束了,時鐘線才回到高電平.這時主機時鐘和SCL的狀態一致,所有的主機開始計數他們的高電平周期.第一個結束高電平的主機將SCL線重新拉低.
這樣的話,同步的SCL時鐘的低電平周期由所有主機中最長的低電平周期決定,高電平周期由最短的高電平周期決定.
仲裁
仲裁和同步一樣,都是在系統中多于一個主機條件下協議要求的一部分.從機不參與仲裁處理.只有當總線空閑時,主機才可以開始一個傳輸.兩個主機可能在開始條件規定的最小保持時間(tHD;SDA)內產生一個開始條件,結果總線上產生一個有效的開始條件.這個時候就需要仲裁來決定哪個主機完成它的傳輸.
仲裁處理是逐個bit進行的.在每個bit,當SCL為高,每個主機都check一下來看看SDA的電平是否和它發送的電平吻合.這個過程可能會持續很多個bit.只要傳輸是同一的,那么兩個主機可以無誤的完成完整的傳輸.當一個主機試著發送高,但是檢測到SDA為低,那么這個主機知道自己失去仲裁然后關掉自己的SDA輸出.另外的主機就會去完成它的傳輸.
在仲裁處理過程中沒有信息丟失.失去仲裁的主機在它失去仲裁的字節末尾處產生時鐘脈沖,當總線空閑時必須重啟它的傳輸.
如果一個主機包含從機的功能,當它在尋址階段丟失仲裁,那么贏得仲裁的主機可能會尋址它.丟失仲裁的主機必須立即切換到它的從模式.
下圖顯示了兩個主機的仲裁處理.在主機產生的DATA1和SDA線的實際電平的值出現不同時,DATA1的輸出就關掉了.主機1失去了仲裁.贏得仲裁的主機2的傳輸數據不受影響.

因為I2C總線只是僅由地址來控制,數據只由贏得仲裁的主機發送,這里沒有最重要的主機,在總線上也沒有優先級順序.
在仲裁處理正在進行的時候,一個主機發送重復的開始條件或者是終止條件而另一個主機仍然在發送數據,那么這時候有一個未定的狀態.換句話說,下面的條件下會出現這種情況:
主機1發送重復的開始條件,主機2發送一個數據位
主機1發送終止條件,主機2發送一個數據位
主機1發送重復的開始條件,主機2發送終止條件
評論