I2C電路故障排除---邊沿時間與杜邦線
阿新 • • 發佈:2019-02-11
- 背景
計劃做一個基於wifi的家庭溫度溼度監控裝置,於是網購一溫度溼度感測器模組HTU21D,採用3.3v電源供電,I2C介面。之前在迷你四軸上用過MPU6050,也是I2C介面的。將感測器連線到STM32C8最小系統板上後,移植迷你四軸中的軟體模擬I2C協議程式碼,編寫了HTU21D驅動程式,開始測試。 - 回合1
先試著讀取了一下HTU21D的使用者暫存器user_register的預設值,居然讀到的是0x00,其預設值應是0x01。上示波器看波形,發現給出I2C的起始訊號S正常,緊跟著的裝置地址0x80訊號給出後,SDA線在第9個時鐘週期為高電平,收不到ACK。
由於這個I2C程式碼是以前用過的,程式碼應該沒問題,並且讀使用者暫存器僅呼叫了I2C_Start()和I2C_WriteByte(uint8_t Data)函式就收不到ACK了,不會是對HTU21D的操作不符合它本身的指令和資料順序的原因。考慮到之前遇到過I2C裝置本身有故障,折騰了很久才發現,懷疑這個HTU21D是壞的。於是聯絡賣家,賣家說不會壞,於是發給我一個測試程式,讓我用他的程式試試。把賣家發的hex檔案燒進片子,串列埠助手看收到的資料,能正確測量溫度和溼度。看來HTU21D是好的。 - 回合2
用賣家的程式測試時,在示波器上看到SCL週期為20us,I2C的位速率為50kbps。而我的程式I2C速率接近250k,於是懷疑是不是HTU21D不支援這麼高的位速率。仔細看了下晶片手冊,最高可以支援到400kbs。可是為什麼用賣家的程式就沒問題呢?兩個不同的程式,使用的電路是完全一樣的,STM32最小系統板和HTU21D感測器直接通過四根20cm左右的杜邦線連線的,邊沿時間應該是一樣的。
又從網上找了幾個別人寫的I2C程式和HTU21D程式,有C51核心的,有STM32的,但是都不能用,從程式程式碼上看都沒什麼問題。再轉過頭來修改自己的I2C程式,加長了位延時,把I2C位速率降了下來,通過示波器看和賣家給的程式波形一樣了,把示波器探頭從板子上取下來,通過串列埠助手看HTU21D的hold master方式下的測量資料,沒有讀數。 - 回合4
懷疑是波形的邊沿時間過長,超出了HTU21D允許的上升沿時間。用示波器看上升時間,對比了賣家給的程式和我自己的程式的波形的上升時間,都是比HTU21D的資料手冊給出的最大允許上升時間400ns要長的,應該是示波器的效能問題。上升沿時間由I2C總線上的上拉電阻的值和總線上的電容Cb有關。那麼減小上升時間的手段就有2種,一是減小上拉電阻,而是減小匯流排電容。顯然通過縮短導線來降低分佈電容更簡單,於是不用杜邦線了,直接把HTU21D通過一個一頭兒是針另一頭兒是座子的接外掛連線到最小系統板上,再接上示波器,波形正常,程式執行正常,可以測量溫度和溼度了。至此已證實確實是上升時間過長導致的問題。可是為什麼賣家給的程式可以使用杜邦線呢?決定繼續折騰。 - 回合5
改回杜邦線連線,再下載賣家給的程式,接上示波器,從串列埠助手看資料,一起正常。再下載我的程式,奇怪的是居然也可以正常測資料了。那之前有為什麼不行呢?自習想了想,和前面回合3中唯一的不同就是,現在接了示波器探頭。於是把探頭從板子上斷開,果然立即就沒資料了。再把賣家的程式燒進去,這下發現,如果不接示波器也是無法測量的。看來是示波器探頭改變了匯流排的分佈電容。百度了“示波器探頭對分佈電容的影響”,確實如我猜測的那樣,度娘告訴我們示波器的探頭不僅由於載入效應使得測量的訊號有失真,還會對被測電路產生影響。不過一般都只說示波器探頭在測量MHz級的訊號時才考慮探頭對訊號的影響,對於這個不到300kbps的I2C電路的上升時間也會產生影響確是沒料到的。而且,網上的資料的提法是接示波器探頭會使上升時間變長,可是這次我的經歷似乎是示波器探頭使上升時間縮短了。經過嘗試,發現即使不接示波器,僅僅用手拿著金屬鑷子去夾著SCL線,也可以起到同樣的效果,HTU21D可以測量溫度和溼度。 - 回合6
用那個雙頭接外掛可以解決問題,可是不方便固定。把HTU21D模組上的I2C上拉電阻從4.7k改為1k也許也能解決問題,可是那個電阻是0603的,我只有0805的。那麼還有什麼辦法呢?忽然想到作為SCL和SDA兩根線的杜邦線是並在一起的,撕開之後會不會有用呢?馬上撕開試試,果然可以。兩根杜邦線並在一起,分佈電容較大,可以用類似平板電容的計算公式解釋,導線相當於兩個平板電極,絕緣層是電介質,導線間距就是電極平面之間的距離,距離越近,電容越大。