1. 程式人生 > 其它 >IIC死鎖解決辦法?

IIC死鎖解決辦法?

目錄

1、現象

2、原因

3、解決方法

4、相關博文


1、現象

        I2C死鎖時表現為SCL為高,SDA一直為低。例如:

1.1、正常情況該部分資料                         

       正常情況slave返回一個byte資料:0x00(該位元組8bit都是0)

1.2、異常發生時該部分資料

         出現該情況原因:因為此時從機正在發資料給主機,但是此時主機因為重啟,所以clk被上拉電阻一直置為高。從機此時傳送給主機的資料位剛好是低電平,若clk不為低,從機講一直保持低電平資料(CLK為低:SDA改變資料;CLK為高:SDA資料保持)。
 

2、原因

        在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匯流排進入死鎖狀態。

3、解決方法

(1)儘量選用帶復位輸人的I2C從器件
(2)將所有的從I2C裝置的電源連線在一起,通過MOS管連線到主電源,而MOS管的導通關斷由 I2C主裝置來實現。
(3)在I2C從裝置設計看門狗的功能。
(4)在I2C主裝置中增加I2C匯流排恢復程式。每次I2C主裝置復位後,如果檢測到SDA資料線被拉低,則控制I2C中的SCL時鐘線產生9個時鐘脈衝(針對8位資料的情況),這樣I2C從裝置就可以完成被掛起的讀操作,從死鎖狀態中恢復過來。這種方法有很大的侷限性,因為大部分主裝置的I2C模組由內建的硬體電路來實現,軟體並不能夠直接控制SCL訊號模擬產生需要時鐘脈衝。


(5)在I2C總線上增加一個額外的匯流排恢復裝置。這個裝置監視I2C匯流排。當裝置檢測到SDA訊號被拉低超過指定時間時,就在SCL總線上產生9個時鐘脈衝,使I2C從裝置完成讀操作,從死鎖狀態上恢復出來。匯流排恢復裝置需要有具有程式設計功能,一般可以用微控制器或CPLD實現這一功能。
(6)在I2C上串入一個具有死鎖恢復的I2C緩衝器,當緩衝器檢測到輸出側SDA或SCL訊號被拉低30ms時,就自動斷開I2C匯流排輸人側與輸出 側 的連線。並且在輸出側SCL訊號上產生16個時鐘脈衝來釋放匯流排。
        另外,對於有些不標準的I2C裝置,只要總線上傳送從機地址就會有響應。這樣由於從機的錯誤響應,使得各個I2C匯流排異常,甚至鉗住匯流排,導致 I2C 匯流排進人一種死鎖狀態。對於這樣的不標準I2C裝置,單獨使用一個匯流排,避免干擾,或者單獨一個獨立引腳,控制電源。

        對於I2C要求不高的裝置最好用模擬I2C實現,控制靈活,則不會死鎖!

4、相關博文

        另外,附上幾個介紹相關問題的幾個連結:

I2C死鎖及解決方法_Frey_Liu的部落格-CSDN部落格_i2c死鎖

I2C SDA SCL被拉低問題分析_qq_37311509的部落格-CSDN部落格_i2c sda不能完全拉低