I2C總線被佔用

轉發網易DP先生關於I2C的博文,便於學習時查找
最近發現訪問I2C設備時,主設備復位可能會引起i2C死鎖,表現爲SCL爲高,SDA一直爲低,後發現是從設備拉死i2c總線,從設備斷電之後,SDA變高,上電後通

信正常。後來通過拉低SCL信號線,SDA就會自動變成高電平,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總

線進入死鎖狀態。

 方法

    (1)儘量選用帶復位輸人的I2C從器件。

    (2)將所有的從I2C設備的電源連接在一起,通過MOS管連接到主電源,而MOS管的導通關斷由I2C主設備來實現。
    (3)在I2C從設備設計看門狗的功能。

    (4)在I2C主設備中增加I2C總線恢復程序。

    每次I2C主設備復位後,如果檢測到SDA數據線被拉低,則控制I2C中的SCL時鐘線產生9個時鐘脈衝(針對8位數據的情況,“9個clk可以激活”的方法來自NXP

的文檔,NXP(Philips)作爲I2C總線的鼻祖,這樣的說法是可信的),這樣I2C從設備就可以完成被掛起的讀操作,從死鎖狀態中恢復過來。

I2C總線死鎖原因及解決方法 - dp - dp: 生活的腳步,進步的點滴...

    這種方法有很大的侷限性,因爲大部分主設備的I2C模塊由內置的硬件電路來實現,軟件並不能夠直接控制SCL信號模擬產生需要時鐘脈衝。 或者,發送

I2C_Stop條件也能讓從設備釋放總線。

    如果是GPIO模擬I2C總線實現,那麼在I2C操作之前,加入I2C總線狀態檢測I2C_Probe ,如果總線被佔用,則可嘗試恢復總線,待總線釋放後,再進行操作

。要保證I2C操作最小單元的完整性,不被其他事件(中斷、高優先級線程,等)打斷。

   (5)在I2C總線上增加一個額外的總線恢復設備。這個設備監視I2C總線。當設備檢測到SDA信號被拉低超過指定時間時,就在SCL總線上產生9個時鐘脈衝,使

I2C從設備完成讀操作,從死鎖狀態上恢復出來。總線恢復設備需要有具有編程功能,一般可以用單片機或CPLD實現這一功能。

    (6)在I2C上串人一個具有死鎖恢復的I2C緩衝器,如Linear公司的LTC4307是一個雙向的I2C總線緩衝器,並且具有I2C總線死鎖恢復的功能。LTC4307總線輸

入側連接主設備,總線輸出側連接所有從設備。當LTC4307檢測到輸出側SDA或SCL信號被拉低30ms時,就自動斷開I2C總線輸入側與輸出側的連接.並且在輸出側

SCL信號上產生16個時鐘脈衝來釋放總線。當總線成功恢復後,LTC4307會再次連接輸入輸出側,使總線能夠正常工作。

 

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