問題描述:
為利用i2c協議實現
kv5晶元與
ms5611
氣壓計晶元的通訊,在初始化
i2c協議(包括引腳復用,設定波特率)後,主機給從機傳送啟動訊號、從機位址及讀寫位(
r/w)後,檢測不到應答位(
ack,低電平)。利用示波器觀測
sda和
scl訊號,如下圖。
可以看到,應答位有拉低現象,說明ms5611接收到自身位址及讀寫位後有應答,但拉低能力不夠,
kv5沒有識別到。
解決方法:
下圖是kv5晶元與
ms5611
晶元外部電路連線圖,
sda和
scl均為外部上拉電路。
硬體電路確定無誤,查閱資料找到解決方法,當復用引腳為i2c通訊時,需將
port
口設定為開漏(
od),即
port_pcr_ode位置1
。修改後,檢測到
sda和
scl的正確波形如下圖:
開漏輸出:即mosfet漏極開路輸出,跟集電極開路輸出是十分類似的。將三極體換成
mosfet
場效電晶體即可。以下分析三極體集電極開路輸出(
oc門)結構,如圖
1所示,右邊的那個三極體集電極什麼都不接,所以叫做集電極開路(左邊的三極體為反相之用,使輸入為「
0」時,輸出也為「
0」)。對於圖
1,當左端的輸入為「
0」時,前面的三極體截止(即集電極
c跟發射極
e之間相當於斷開),所以
5v電源通過
1k電阻加到右邊的三極體上,右邊的三極體導通(即相當於乙個開關閉合);當左端的輸入為「
1」時,前面的三極體導通,而後面的三極體截止(相當於開關斷開)。
可將圖1簡化成圖
2的樣子。圖
2中的開關受軟體控制,「
1」時斷開,「
0」時閉合。很明顯可以看出,當開關閉合時,輸出直接接地,所以輸出電平為
0。而當開關斷開時,則輸出端懸空了,即高阻態。這時電平狀態未知,如果後面乙個電阻負載(即使很輕的負載)到地,那麼輸出端的電平就被這個負載拉到低電平了,所以這個電路是不能輸出高電平的。所以
od門要得到高電平狀態,需要外接上拉電阻。
推挽輸出:是有兩個三極體,把上圖3的上拉電阻也換成乙個開關,當要輸出高電平時,上面的開關通,下面的開關斷;而要輸出低電平時,則剛好相反。比起oc或
od,推挽結構高、低電平驅動能力都很強。
由於沒有找到kv5/k60晶元
port
口內部的電路圖,找到乙個
stm32
的i/o
口結構圖,兩者應該大同小異。如下圖:
i/o分為輸入輸出兩個通道,
設定成輸出時,輸入也是有效的
,但要在輸出高電平時將引腳可靠拉低
,這也是i2c協議
sda線為什麼可以既作輸入又作輸出的原因。
stm32的輸出是分為開漏輸出和推挽輸出,開漏輸出時,
n-mos
被啟用,
p-mos
未被啟用。推挽輸出時,
n-mos
、p-mos
均被啟用。當
i/o埠被配置為輸出時,圖中肖特基觸發器是被啟用的,但不管是開漏輸出還是推挽輸出,兩個mos都是「懸空」狀態,即高阻態的,可以對
輸入資料暫存器的讀訪問可得到
i/o狀態。輸入通道上有弱上拉電阻和弱下拉電阻,在作輸入時,兩個電阻是被禁止的,否則影響輸入電平讀取。
現分析應答位拉低能力不夠的原因,由於沒有使能開漏,但外部是有上拉電路的,所以可以正常輸出高低電平,即主機發給從機的電平變化都是正確的(即時外部沒有配置上拉電阻,也可以使能內部上拉電路,同樣可輸出正常電平,外部上拉
的好處是輸出電平可以根據外部上拉
電壓來定,
提高驅動能力,同時也可以自行選取上拉電阻阻值),當讀取氣壓計反饋應答訊號時,引腳作輸入,未使能開漏(kv5手冊上沒寫,我自己理解是應該就是推挽結構)可能導致輸入通道上的弱下拉上拉電阻沒被禁止,導致氣壓計輸入低電平時,弱下拉電阻把輸入電平太高。
硬體改版引起的I2C異常
最近公司有一款新版硬體,在測試時發現原有的i2c通訊測試程式執行失敗,從i2c從裝置rx8025中無法讀取到資料。使用示波器的時候,也無法在時鐘線scl上看到時鐘訊號。但是在測試資料線sda的時候,偶爾能看到一些資料。如果使用示波器錶筆點在測試的訊號線上,有時能讀到正確的資料 如果不這樣做,幾乎看不...
Uboot關於i2c和EEPROM的命令
在uboot命令列下輸入i2c並回車,會列印出i2c所有命令的使用方法 比如i2c dev會列印出目前掛載的i2c裝置 i2c md命令是從i2c裝置讀取資料,在這裡本人用的是beaglebone black,然後就選擇eeprom這個內建的i2c裝置進行讀取 要注意的是md命令的引數,第乙個是ch...
Zynq7020 16位i2c位址的讀寫除錯方法
裡面介紹的i2cset,i2cget等的指令,都是基於8位位址的,但今天我遇到了個問題,需要操作16位位址,顯然這幾個指令已經無法滿足我的需求,這個時候我發現i2ctool的4.0以上版本新加入了乙個新的指令 i2ctransfer。i2ctransfer可以對i2c裝置指定定長度進行讀寫操作,下面...