1. 程式人生 > >I2C匯流排及匯流排阻塞

I2C匯流排及匯流排阻塞

這個問題以前還真遇到過但是沒有仔細分析過原因,這次被問到這個問題傻了,看到網上的一些相關文件後,整理了這篇文章,主要分析產生原因和解決辦法。

首先還是看看I2C相關的一些步驟的匯流排狀態:



死鎖匯流排表現為:SCL為高,SDA一直為低

從:正常時序下:SDA訊號是在SCL為低的狀態下改變,即從應答SDA為低電平時,此時SCL應為為低電平

原因:當master正在和slave通訊,如果master正好發生打算髮第9個時鐘,此時SCL為高slave裝置是先拉低SDA訊號(作為ACK訊號),等待master裝置SCL由高變低,“取走”ACK訊號後,slave再釋放SDA為高。但如果此時時序被打亂,例如master 

i2c通訊時突然復位,master的SCL還沒來得及變低,直接變成高電平,此時slave還在等待SCL變低,所以一直拉低SDA

master:SDA被從拉低,故master認為i2c匯流排佔用,一直等待SDA變高

這樣master/slave進入一個相互等待的死鎖過程。




解決方法:(軟體辦法 產生大於9個時鐘scl脈衝)

    (1)儘量選用帶復位輸人的I2C從器件。(master reset後,slave也需要reset)

    (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緩衝器,如Linear公司的LTC4307如圖2所示:LTC4307是一個雙向的I2C
匯流排緩衝器,並且具有I2C匯流排死鎖恢復的功能。LTC4307匯流排輸入側連線主裝置,匯流排輸出側連線所有從裝置。當LTC4307

檢測到輸出側SDA或SCL訊號被拉低30ms時,就自動斷開I2C匯流排輸人側與輸出側的連線.並且在輸出側SCL訊號上產生16個時鐘脈衝來釋放匯流排

當匯流排成功恢復後,LTC4307會再次連線輸人輸出側,使匯流排能夠正常工作。

LTC4307: 具有低偏移和阻塞匯流排恢復能力的I2C匯流排緩衝器

LTC4307還具有阻塞匯流排恢復電路,通過檢測和清除阻塞匯流排,幫助保持系統統一性。如果序列資料輸出SDA或序列時鐘輸出SCL為低電平的時間超過30ms,那麼LTC4307就自動斷開資料和時鐘匯流排的連線,並在SCL埠產生多達16個時鐘脈衝,嘗試釋放該匯流排。當匯流排變至空閒狀態時,將需要立即使能一條線路,以恢復正確的操作,而本質上,LTC4307將有效地起到免除一般系統復位之需的作用。

LTC4307效能概要:

  • 匯流排處於阻塞低電平的時間≥30ms 時,自動斷開SDA/SCL連線