1、前言
這段時間一直在折騰自己的畢設(shè),第二塊板子到手基本上調(diào)通了所有的內(nèi)容,還有幾塊芯片還在寫測試代碼。
其中有一塊BMP280氣壓傳感器,這塊芯片在第一塊板子中是完全能用的,因此可以排除是代碼以及原理圖的問題。
在這一版的設(shè)計中,BMP280單獨占用了一組I2C1,但是在焊接之后測試過程中發(fā)現(xiàn)不能與BMP280建立完整的通訊。
由于我所有的器件都是手焊的,并且該器件屬于QFN封裝,在焊接上重復(fù)了好幾遍,并且也更換過了器件,但是依舊無法解決問題。
昨天晚上突發(fā)奇想,干脆把I2C1的SCL和SDA線飛到臨近的一組I2C上,接著在初始化的過程中取消掉I2C1的功能將其空置。
居然莫名其妙的能夠通訊了。
但是這樣子實在是太丑了,于是今天嘗試能不能解決掉原來I2C1為什么不能通訊的問題。
2、奇怪的引腳狀態(tài)
在GPIO中有一個只讀寄存器IDR,它記錄芯片主控測得的引腳電平。
查詢IDR寄存器的地址值(STM32U0中GPIO的基地址是0x50000000,GPIOB的偏移地址是0x400,IDR寄存器的偏移地址是0x10,因此GPIOB的IDR寄存器的位置是0x50000410)發(fā)現(xiàn)其值是0x3EE2
PB6和PB7初始化都是正常的高電平狀態(tài),但是使用過I2C之后。
該值變成了0x3E22,對應(yīng)著PB7/6始終為低電平。
并且將I2C1總線釋放后,將其配置為普通的GPIO模式,開漏輸出上拉,強制拉高,其值依舊為0。
可能正是這種異常狀態(tài),導(dǎo)致了I2C1不能正常使用。
3、硬件I2C的死鎖?
在論壇和平時的了解中,偶爾有人會提到STM32系列的硬件I2C出現(xiàn)死鎖問題。
大體的原因是在數(shù)據(jù)傳輸過程中,主接收器在接收到最后一個字節(jié)后會發(fā)送ACK信號,這會導(dǎo)致從機持續(xù)等待數(shù)據(jù),從而造成總線死鎖,這據(jù)說是STM32的硬件I2C為了避開飛利浦的I2C專利而不得已留下的BUG。
但是I2C的專利在早些年就已經(jīng)過期了,如果是在F103中遇到的這種問題我還能理解(103的硬件I2C我好像也沒遇到死鎖的問題)。
但是STM32U0作為較新的產(chǎn)品,出現(xiàn)I2C死鎖的BUG感覺是不太應(yīng)該。
4、解決辦法
后來為了測試電壓到底是多少,在I2C初始化之后,發(fā)現(xiàn)實際的情況居然是SCL(PB6)的電壓為2.5V+
這是一個非常經(jīng)典的空置電壓,這說明SCL引腳并沒有被上拉。由于我一般沒有習(xí)慣接上拉電阻,都是靠GPIO的內(nèi)部上拉來充當(dāng)上拉電阻。
那么顯然問題就是SCL引腳的內(nèi)部上拉出現(xiàn)了問題。
但是明明代碼中很明顯的寫的是內(nèi)部上拉,而且非常奇怪的是I2C4明明是配置的內(nèi)部上拉模式,但是I2C1飛到I2C4的時候(飛線)依舊無法使用I2C1。并且如果使能I2C1的話會同樣的導(dǎo)致I2C4癱瘓出現(xiàn)同樣的問題。
查詢芯片手冊得知GPIO的PUPDR寄存器記錄引腳的上下拉狀態(tài),查詢該地址的值發(fā)現(xiàn)PB6,PB7均是正常的上拉,但是引腳懸空確實實打?qū)嵈嬖诘膯栴}。于是看看能不能通過外接上拉電阻的情況來解決問題。
當(dāng)在I2C1中接入4.9K的上拉電阻后,發(fā)現(xiàn)BMP280正常使用。
并且使用完I2C后,IDR寄存器的值也是正常的顯示高電平。
5、疑問
主要是奇怪為什么同樣的I2C總線,一組I2C1不能使用,其他的I2C總線可以正常使用。
而且如果同時開啟I2C1并且和其他I2C總線連接到一起,會導(dǎo)致其他I2C總線的SCL引腳處于懸空狀態(tài),從而讓其他的I2C總線失效~~~很奇怪。