您當前的位置:首頁 > 繪畫

“I2C”的那些坑,如何邁過去?

作者:由 陳志發 發表于 繪畫時間:2019-11-28

一般情況下,I2C裝置焊接沒什麼問題,按照裝置手冊一步步來,基本上就順風順水能夠用起來。如果這麼一個簡單的東西,有時候想要的結果死活不出來,反覆的檢查問題的原因,查詢解決辦法,核查裝置的資料手冊,甚至傳送和接收的每一條命令與資料都知道是什麼意思,仍然無法解決問題,那該怎麼辦呢?

本文主要針對I2C裝置,講解如何解決I2C裝置主機與從機直接無法正常資料互動的問題,側重點是針對硬體設計不太合理、I2C裝置設計不標準導致匯流排故障的情況,並且透過分析現象,提出解決方案。對於在裝置初始化中,沒有設定相應的

暫存器

或者傳送命令,而導致的無法獲取想要的資料情況,不作詳細介紹。

1

I2C基本用法

I2C匯流排是一種簡單、雙向二線制同步序列匯流排。所有主機在 SCL 線上產生它們自己的時鐘來傳輸總線上的報文,SDA 線傳輸每個

位元組

必須為 8 位,每次傳輸可以傳送的位元組數量不受限制,每個位元組後必須跟一個響應位。在空閒狀態時,SCL 與 SDA 均為

高電平

通常一些低功耗I2C裝置,晶片引腳使用上拉輸出即可滿足與其正常資料互動,還有一些I2C裝置,則需要在總線上外加一個

上拉電阻

,此時相應的 I/O 配置成開漏輸出,其他的按照晶片手冊進行標準配置。

2 硬體問題彙總

2.1 無法正常拉高拉低引腳

首先確定 SDA 與SCL 引腳能夠被拉高、拉低,檢測方式直接軟體控制 I/O 口輸出引腳低電平/高電平,測量引腳電壓是否能夠隨著晶片引腳的設定輸出相應的狀態。

如果不能被拉低,檢測虛焊、上拉電阻斷開、I2C裝置是否正常、晶片引腳是否損壞等問題,確保能夠正常被拉高或者拉低。

2.2 電氣特性無法滿足

如果正常拉高、拉低的情況下,依然無法正常讀取資料。通常建議,根據負載電流更換小阻值的電阻。

如果需要詳細知道原因,就具體查詢I2C裝置

電氣特性

。大多數I2C裝置電氣特性,大致下圖所示

“I2C”的那些坑,如何邁過去?

通常這塊內容在I2C裝置電氣特性這一塊,主要講解電平拉高拉低的最長時間、最短時間,以及處於高電平與電平的閾值與持續時間等等內容。

硬體設計,為了降低微控制器的功耗與保護晶片引腳,在滿足負載電流和負載電容相關要求的前提下,阻值設定通常比較大。如果同一個總線上掛載多個I2C裝置, 即使在 I/O口配置正確的前提下,也會導致驅動能力不足。

現象是拉高電壓不足,在拉高、拉低過程中消耗時間過長。這兩個問題通常還引起資料線與時鐘線:拉高時,高電壓持續時間過短;拉低時,低電壓持續時間過短。用示波器抓取圖形:從波形上看,顯示是尖波、斜波、

雜波

等不符合I2C裝置電氣特性的波形;從資料上看,資料線高電平持續時間過小 ,上升沿時間過長 ,下降沿時間過長等等資料超出裝置電氣特性的有效值。典型雜波圖,如下所示

“I2C”的那些坑,如何邁過去?

如果出現此類異常,建議更換小一點的電阻,用來增強匯流排驅動能力,提高電平轉換速度。應當注意的是每個MCU的耐受電流不一樣,減小電阻應避免超過相應引腳承受電流的最大值。

3 SDA 死鎖

如果I2C裝置的資料偶爾能夠正確獲取,但是仍然會在匯流排傳送資料或者命令的時候,爆出匯流排讀寫錯誤,那麼有可能遇到下面的死鎖問題,死鎖時候,就是資料線被拉低,主機無法拉高。死鎖一般發生在從機上,且為

資料線死鎖

。因為I2C匯流排是共享的,如果需要確定,是否是從機死鎖,可以參照下面兩幅圖,串聯電阻進行測試

“I2C”的那些坑,如何邁過去?

如上圖所示,如果從機死鎖,即從機拉低電平,此時檢測到的電壓為1/3 Vcc。

“I2C”的那些坑,如何邁過去?

如上圖所示,如果主機死鎖,即主機拉低電平,此時檢測到的電壓為 1/11 Vcc。依據這個原理,可以準確判定

死鎖

的具體位置,多個感測器依據類似方式進行定位。

3.1 反覆重啟導致死鎖

3.1.1 現象

如果裝置需要反覆重啟,很有可能在從機裝置返回資料的時候,SDA被鎖住。具體原因是從機裝置在回資料,還沒有傳送完成,主機時鐘消失,從機等待時鐘訊號, MCU重啟,如果從機裝置的電源沒有復位,從機繼續等待 MCU 時鐘訊號,資料一直被鉗住,匯流排無法完成資料互動。

3.1.2 解決方式

解決重啟導致匯流排死鎖,一種方式可以如同

rt-thread

驅動解決方式一樣,在系統復位的時候,提供9個時鐘訊號,解初

匯流排死鎖

;另一種是在按下復位鍵初始化的時候,給從機裝置電源斷電重啟,這個需要引腳控制。

3.1.3 9 個時鐘訊號

I2C裝置進行讀寫操作的過程中,在從機鉗住匯流排的期間,MCU 異常復位,會導致 SDA 死鎖,異常產生出現在倆個階段:從機響應階段、從機發送資料階段。下面將針對這兩種異常,對

時鐘訊號

進行解釋,並且總結其他原因,得出結論。

(a) 從機響應階段

MCU 在開始訊號後傳送地址,得到從機裝置響應,準備開始返回資料,在這個時候,從機將 SDA 訊號拉為

低電平

,如果 MCU 異常復位,會導致總線上 SCL 停止傳送時鐘訊號,從機等待 MCU 的時鐘訊號,產生鉗住並且拉低 SDA 的現象。如果想要解鎖 SDA,從機需要 9 個時鐘訊號,使得從機完成響應,釋放 SDA 。

(b) 從機發送資料階段

如果從機響應完成了,開始給MCU返回資料。這個資料有八位,每一位都有可能為低,如果在資料低位,MCU異常復位,停止傳送時鐘訊號,從機就會等待 MCU的時鐘訊號,產生鉗住並且拉低SDA的現象。如果想要解鎖SDA,從機需要 1-8個時鐘訊號,使得從機完成資料響應,釋放 SDA 。

(c)其他情況

在從機一個8位資料傳送完成後,等待MCU響應, 即使屬於MCU的,從機不再鉗住 SDA,沒有時鐘,資料互動停止。

在主機發送資料階段,匯流排所有權在主機,主機異常,資料互動停止,匯流排釋放。所以,這些情況下,不存在SDA死鎖的情況。

(d)結論

綜上所述,解鎖SDA從機最多需要 9 個時鐘訊號,也就是異常復位後,MCU至少傳送需要9個時鐘訊號,完成 i2c 匯流排的SDA解鎖。所以,RT_Thread 為了避免此類問題的產生,在i2c驅動初始化,對匯流排進行判斷,判斷是否需要解鎖,如果需要,就進行解鎖,確保 i2c裝置不會因為這個問題導致資料互動失敗。

3.2 多個I2C裝置導致死鎖

多I2C裝置除了異常復位導致死鎖,還會形成相互干擾的問題,一般情況下,不會把同種從機地址掛在同一條總線上,但除此之外,有些I2C裝置設計不是按照標準的I2C

匯流排協議

設計,在I2C匯流排共享的前提條件下,有的裝置只要總線上從機地址就會有響應。這樣由於從機的錯誤響應,使得各個I2C匯流排異常,甚至鉗住匯流排,導致

I2C匯流排

進人一種死鎖狀態。

解決方式,這樣的不標準i2c裝置,單獨使用一個匯流排,避免干擾,或者單獨一個獨立引腳,控制電源。 合作微信xyd201606 QQ:3306607541

標簽: I2C  從機  匯流排  死鎖  SDA