正常情況下,I2C匯流排協議能夠保證匯流排正常的讀寫操作。但是在某些異常情況下會導致I2C匯流排鎖死。例如主控制器突然復位、或者I2C總線上存在干擾、或者電源異常等都可能導致I2C匯流排鎖死。
在I2C主裝置進行讀寫操作的過程中,主裝置在開始訊號後控制SCL產生8個時鐘脈衝。然後拉低SCL訊號為低電平,在這個時候,從裝置輸出應答訊號,將SDA訊號拉為低電平 如果這個時候主裝置異常復位,SCL就會被釋放為高電平。此時,如果從裝置沒有復位,就會繼續I2C的應答,將SDA拉為低電平,直到SCL變為低電平,才會結束應答訊號。而對於I2C主裝置來說,復位後檢測SCL和SDA訊號,如果發現SDA訊號為低電平,則會認為I2C匯流排被佔用,會一直等待SCL和SDA訊號變為高電平。這樣,I2C主裝置等待從裝置釋放SDA訊號,而同時I2C從裝置又在等待主裝置將SCL訊號拉低以釋放應答訊號,兩者相互等待,I2C匯流排進入一種死鎖狀態。
同樣,當I2C進行讀操作,I2C從裝置應答後輸出資料,如果在這個時刻I2C主裝置異常復位而此時I2C從裝置輸出的資料位正好為0,也會導致I2C匯流排進入死鎖狀態。
廣州致遠電子ARM核心板使用IIC裝置時,遇到匯流排死鎖是如何讓匯流排死鎖恢復呢,常用方法如下:
(1) 儘量選用帶復位輸人的I2C從器件,從I2C匯流排死鎖產生的原因可以發現I2C匯流排死鎖的一個必要條件是主裝置復位了而從裝置沒有復位。如果從裝置選用帶復位輸入的晶片,將主從裝置的復位訊號連線在一起,當外部產生復位事件時,主從裝置同時復位,這樣就不會發生I2C匯流排死鎖現象了。 這種方法的缺點也是顯而易見的,首先,大部分I2C從器件都沒有復位輸入,器件選型受到了很大的限制;其次,這種對於主裝置整合看門狗引起的復位也沒有效果。
(2) 將所有的從I2C裝置的電源連線在一起,透過M0S管連線到主電源,而MOS管的導通關斷由I2C主裝置來實現一般來說,I2C主裝置都是具有運算單元的處理器。控制功能可以透過處理器的GPIO來實現。每次主裝置復位時,執行程式控制GPIO關斷MOS,使從裝置失去電源。 然後延時一段時間後再導通MOS管,給從裝置上電,從而達到讓從裝置強制復位的效果。這種方法能彌補第一種方法的不足,但是會增加電源設計的複雜性,影響Layout設計時電源的完整性; 同時還需要更改處理器的底層boot程式碼,影響底層軟體的通用性和可移植性。
(3) 在I2C從裝置設計看門狗的功能。當I2C從裝置檢測到自身處於應答狀態或者低電平輸出超過指定時間時,看門狗動作,復位I2C從裝置。這種情況下不用增加額外的硬體設計,但是要求I2C從裝置具有可程式設計功能,比較適合從裝置是微控制器或CPLD的情況。
(4) 在I2C主裝置中增加I2C匯流排恢復程式。 每次I2C主裝置復位後,如果檢測到SDA資料線被拉低,則控制I2C 中的SCL時鐘線產生9個時鐘脈衝(針對8位資料的情況),這樣I2C從裝置就可以完成被掛起的讀操作,從死鎖狀態中恢復過來。這種方法有很大的侷限性,因為大部分主裝置的I2C模組由內建的硬體電路來實現。軟體並不能夠直接控制SCL訊號模擬產生需要時鐘脈衝。使用此種方法可以使用IO模擬I2C,SCL時鐘易控制。
(5) 在I2C總線上增加一個額外的匯流排恢復裝置,這個裝置監視I2C匯流排。當裝置檢測到SDA訊號被拉低超過指定時間時,就在SCL總線上產生9個時鐘脈衝,使I2C從裝置完成讀操作,從死鎖狀態上恢復出來。匯流排恢復裝置需要有具有程式設計功能,一般可以用微控制器或CPLD實現這一功能。
(6) 在I2C上串人一個具有死鎖恢復的I2C緩衝器。
正常情況下,I2C匯流排協議能夠保證匯流排正常的讀寫操作。但是在某些異常情況下會導致I2C匯流排鎖死。例如主控制器突然復位、或者I2C總線上存在干擾、或者電源異常等都可能導致I2C匯流排鎖死。
在I2C主裝置進行讀寫操作的過程中,主裝置在開始訊號後控制SCL產生8個時鐘脈衝。然後拉低SCL訊號為低電平,在這個時候,從裝置輸出應答訊號,將SDA訊號拉為低電平 如果這個時候主裝置異常復位,SCL就會被釋放為高電平。此時,如果從裝置沒有復位,就會繼續I2C的應答,將SDA拉為低電平,直到SCL變為低電平,才會結束應答訊號。而對於I2C主裝置來說,復位後檢測SCL和SDA訊號,如果發現SDA訊號為低電平,則會認為I2C匯流排被佔用,會一直等待SCL和SDA訊號變為高電平。這樣,I2C主裝置等待從裝置釋放SDA訊號,而同時I2C從裝置又在等待主裝置將SCL訊號拉低以釋放應答訊號,兩者相互等待,I2C匯流排進入一種死鎖狀態。
同樣,當I2C進行讀操作,I2C從裝置應答後輸出資料,如果在這個時刻I2C主裝置異常復位而此時I2C從裝置輸出的資料位正好為0,也會導致I2C匯流排進入死鎖狀態。
廣州致遠電子ARM核心板使用IIC裝置時,遇到匯流排死鎖是如何讓匯流排死鎖恢復呢,常用方法如下:
(1) 儘量選用帶復位輸人的I2C從器件,從I2C匯流排死鎖產生的原因可以發現I2C匯流排死鎖的一個必要條件是主裝置復位了而從裝置沒有復位。如果從裝置選用帶復位輸入的晶片,將主從裝置的復位訊號連線在一起,當外部產生復位事件時,主從裝置同時復位,這樣就不會發生I2C匯流排死鎖現象了。 這種方法的缺點也是顯而易見的,首先,大部分I2C從器件都沒有復位輸入,器件選型受到了很大的限制;其次,這種對於主裝置整合看門狗引起的復位也沒有效果。
(2) 將所有的從I2C裝置的電源連線在一起,透過M0S管連線到主電源,而MOS管的導通關斷由I2C主裝置來實現一般來說,I2C主裝置都是具有運算單元的處理器。控制功能可以透過處理器的GPIO來實現。每次主裝置復位時,執行程式控制GPIO關斷MOS,使從裝置失去電源。 然後延時一段時間後再導通MOS管,給從裝置上電,從而達到讓從裝置強制復位的效果。這種方法能彌補第一種方法的不足,但是會增加電源設計的複雜性,影響Layout設計時電源的完整性; 同時還需要更改處理器的底層boot程式碼,影響底層軟體的通用性和可移植性。
(3) 在I2C從裝置設計看門狗的功能。當I2C從裝置檢測到自身處於應答狀態或者低電平輸出超過指定時間時,看門狗動作,復位I2C從裝置。這種情況下不用增加額外的硬體設計,但是要求I2C從裝置具有可程式設計功能,比較適合從裝置是微控制器或CPLD的情況。
(4) 在I2C主裝置中增加I2C匯流排恢復程式。 每次I2C主裝置復位後,如果檢測到SDA資料線被拉低,則控制I2C 中的SCL時鐘線產生9個時鐘脈衝(針對8位資料的情況),這樣I2C從裝置就可以完成被掛起的讀操作,從死鎖狀態中恢復過來。這種方法有很大的侷限性,因為大部分主裝置的I2C模組由內建的硬體電路來實現。軟體並不能夠直接控制SCL訊號模擬產生需要時鐘脈衝。使用此種方法可以使用IO模擬I2C,SCL時鐘易控制。
(5) 在I2C總線上增加一個額外的匯流排恢復裝置,這個裝置監視I2C匯流排。當裝置檢測到SDA訊號被拉低超過指定時間時,就在SCL總線上產生9個時鐘脈衝,使I2C從裝置完成讀操作,從死鎖狀態上恢復出來。匯流排恢復裝置需要有具有程式設計功能,一般可以用微控制器或CPLD實現這一功能。
(6) 在I2C上串人一個具有死鎖恢復的I2C緩衝器。