關於 NXP PCA85073A 實時時鐘讀取數據時出現 IIC 傳輸失敗的原因解析和解決方法

一、前言
     
      對使用 I2C 傳輸的 RTC 外設 PCA85073,在 I2C 傳輸過程中若有復位信號輸入,則有機率出現 I2C 死鎖的狀態,即 SCL為高,SDA一直為低的現象。


二、I2C 基本協議


      在分析問題出現的原因之前,我們首先需對 I2C 信號進行解釋。

      首先 SCL 時鐘和 SDA 數據線都必須是雙向開漏結構,通過總線上的上拉電阻拉到邏輯高電平,當 SCL 與 SDA 為都為高電平時,總線處於空閒狀態。

                                      

      當 SCL 為高,SDA 由高到低的變化為起始信號。
      當 SCL 為高,SDA 由低變高為結束信號,停止信號是由主機發出的。



      當 SCL 為低時,SDA 才能更改電平狀態。


三、I2C “ 掛死 ” 原因解析

      由於是開漏的結構,當 I2C SDA 總線上有任何一個器件拉低總線電平的時候,其它任何器件都無法拉高 SDA 總線,如果 SDA 總線上有一個設備不釋放總線,那麼這條線會一直被這個設備占用,總線上的通信就會暫停。

      一般情況下,從設備在數據傳輸完成後就釋放 SDA 線,總線就會恢復空閒狀態。但在一些情況下,從設備會一直拉低 SDA 線不釋放,這種一般被稱為 “I2C 掛死 ”或 “I2C 死鎖 ”。

      那麼哪種情況下 I2C 會掛死呢?

      上面說過,只有當 SCL 為低電平時,SDA 才能變化電平狀態,當 I2C 在傳輸過程中被意外中斷,總線停留在 SCL 高,SDA 為低的情況,此時總線就會一直被占用,這種情況原因往往是從機拉低 SDA 不釋放,因為若是主機拉低 SDA 不釋放,我們能夠去通過軟體控制主機或者通過復位等操作去解決。而若是從機的原因,由於很多時候 I2C 從機不會帶復位引腳,所以就算對整個系統進行復位也沒辦法解除這種狀態,只能通過上下電進行恢復,這種操作對於很多時候都是無法接受的,例如需要連續運行進行計時的 RTC 外設。

      接下來我們繼續分析

      首先需要看看哪些情況下 I2C 從機會需要拉低 SDA 線

  1. 傳輸數據時,從機發出 ACK 應答
  2. 讀數據,從機傳輸 0 時會拉低 SDA

      那麼出現掛死的最常見的情況就是主機在通訊的過程中產生了復位。由於復位動作通常會立刻執行,也就發不出完整的 CLK 了。那麼等到主機復位完成回來後,SCL 為高,SDA 被從機拉低。主機無法發起 START 起始條件,不能開始下一次與從機的通訊,這稱為 SDA 掛死。


四、問題解決方法

      根據 NXP 的 《I2C-bus specification and user manual》最簡單的解決辦法就是使用 GPIO 模擬 I2C 的連續 9 位時鐘或者更多時鐘,因為協議規定 I2C 的通常傳輸的數據寬度為 8 位和 1 位應答位,額外的時鐘都會被認為是停止信號,所以不管從機處於何種狀態,這種方法都能使從機釋放 SDA ,進入正常的傳輸狀態。


五、問題解決實例

      在使用 I2C 對實時時鐘 PCA85073 讀取數據過程,發現傳輸中間 MCU 出現復位則有機率出現 I2C 掛死的現象,通過 GPIO 模擬時鐘信號可以使 PCA85073 釋放 SDA 線,後續就能進行正常的數據讀取,下圖是通過 GPIO 模擬恢復正常傳輸的時序圖。

 

六、參考文檔

      [1] NXP《I2C-bus specification and user manual》

★博文內容均由個人提供,與平台無關,如有違法或侵權,請與網站管理員聯繫。

★文明上網,請理性發言。內容一周內被舉報5次,發文人進小黑屋喔~

評論