工程師經(jīng)驗分享:采用硬件I2C讀取E2PROM
現象:?jiǎn)纹瑱C采用硬件i2c讀取E2PROM,當單片機復位時(shí),會(huì )有概率出現再無(wú)法與E2PROM通信,此時(shí)SCL為高,SDA一直為低
本文引用地址:http://dyxdggzs.com/article/201710/368906.htm原因:當單片機正在和E2PROM通信,如果主正好發(fā)生打算發(fā)第9個(gè)時(shí)鐘,此時(shí)SCL為高,而從開(kāi)始拉低SDA為低做準備(作為ACK信號),等待主SCL變低后,從再釋放SDA為高。如果此時(shí)正好單片機復位,主SCL還沒(méi)來(lái)得及變低,直接變成高電平,此時(shí)從還在等待SCL變低,所以一直拉低SDA;而主由于復位,發(fā)現SDA一直為低,也在等待從釋放SDA為高。因此主從都進(jìn)入一個(gè)相互等待的死鎖狀態(tài)。
解決方法:最好的方法是采用模擬i2c. 但由于已經(jīng)配置成硬件i2c,程序改為上電或復位改成發(fā)9個(gè)SCL時(shí)鐘信號,使從好釋放SDA。
最近發(fā)現單片機(硬件I2C實(shí)現)讀取E2PROM時(shí)候,單片機復位可能會(huì )引起i2C死鎖,表現為SCL為高,SDA一直為低,后發(fā)現是E2PROM從設備拉死i2c總線(xiàn),從設備斷電之后,SDA變高,上電后通信正常。后來(lái)通過(guò)拉低SCL信號線(xiàn),SDA就會(huì )自動(dòng)變成高電平,i2c總線(xiàn)恢復。后查看一篇文章,講的不錯,特摘錄如下:
在正常情況下,I2C總線(xiàn)協(xié)議能夠保證總線(xiàn)正常的讀寫(xiě)操作。但是,當I2C主設備異常復位時(shí)(看門(mén)狗動(dòng)作,板上電源異常導致復位芯片動(dòng)作,手動(dòng)按鈕復位等等)有可能導致I2C總線(xiàn)死鎖產(chǎn)生。下面詳細說(shuō)明一下總線(xiàn)死鎖產(chǎn)生的原因。
在I2C主設備進(jìn)行讀寫(xiě)操作的過(guò)程中。主設備在開(kāi)始信號后控制SCL產(chǎn)生8個(gè)時(shí)鐘脈沖,然后拉低SCL信號為低電平,在這個(gè)時(shí)候,從設備輸出應答信號,將SDA信號拉為低電平。如果這個(gè)時(shí)候主設備異常復位,SCL就會(huì )被釋放為高電平。此時(shí),如果從設備沒(méi)有復位,就會(huì )繼續I2C的應答,將SDA一直拉為低電平,直到SCL變?yōu)榈碗娖?,才?huì )結束應答信號。而對于I2C主設備來(lái)說(shuō)。復位后檢測SCL和SDA信號,如果發(fā)現SDA信號為低電平,則會(huì )認為I2C總線(xiàn)被占用,會(huì )一直等待SCL和SDA信號變?yōu)楦唠娖?。這樣,I2C主設備等待從設備釋放SDA信號,而同時(shí)I2C從設備又在等待主設備將SCL信號拉低以釋放應答信號,兩者相互等待,I2C總線(xiàn)進(jìn)人一種死鎖狀態(tài)。同樣,當I2C進(jìn)行讀操作,I2C從設備應答后輸出數據,如果在這個(gè)時(shí)刻I2C主設備異常復位而此時(shí)I2C從設備輸出的數據位正好為0,也會(huì )導致I2C總線(xiàn)進(jìn)入死鎖狀態(tài)。
SCL為高,SDA一直為低原因
從:正常時(shí)序下:SDA信號是在SCL為低的狀態(tài)下改變,即從應答SDA為低電平時(shí),此時(shí)SCL應為為低電平(即從設備是先拉低SDA信號,等待主設備SCL由高變低,“取走”ACK信號后,從再釋放SDA為高)。但如果此時(shí)時(shí)序被打亂,例如單片機i2c通信時(shí)突然復位,SCL突然變高,則從設備SDA一直為低,等待SCL變低。
主:SDA被從拉低,故主認為i2c總線(xiàn)占用,一直等待SDA變高這樣主從進(jìn)入一個(gè)相互等待的死鎖過(guò)程。
方法:
最好用模擬I2C實(shí)現,則不會(huì )死鎖
?。?)盡量選用帶復位輸人的I2C從器件。
?。?)將所有的從I2C設備的電源連接在一起,通過(guò)MOS管連接到主電源,而MOS管的導通關(guān)斷由I2C主設備來(lái)實(shí)現。
?。?)在I2C從設備設計看門(mén)狗的功能。
?。?)在I2C主設備中增加I2C總線(xiàn)恢復程序。每次I2C主設備復位后,如果檢測到SDA數據線(xiàn)被拉低,則控制I2C中的SCL時(shí)鐘線(xiàn)產(chǎn)生9個(gè)時(shí)鐘脈沖(針對8位數據的情況),這樣I2C從設備就可以完成被掛起的讀操作,從死鎖狀態(tài)中恢復過(guò)來(lái)。這種方法有很大的局限性,因為大部分主設備的I2C模塊由內置的硬件電路來(lái)實(shí)現,軟件并不能夠直接控制SCL信號模擬產(chǎn)生需要時(shí)鐘脈沖。
?。?)在I2C總線(xiàn)上增加一個(gè)額外的總線(xiàn)恢復設備。這個(gè)設備監視I2C總線(xiàn)。當設備檢測到SDA信號被拉低超過(guò)指定時(shí)間時(shí),就在SCL總線(xiàn)上產(chǎn)生9個(gè)時(shí)鐘脈沖,使I2C從設備完成讀操作,從死鎖狀態(tài)上恢復出來(lái)??偩€(xiàn)恢復設備需要有具有編程功能,一般可以用單片機或CPLD實(shí)現這一功能。
?。?)在I2C上串人一個(gè)具有死鎖恢復的I2C緩沖器,如Linear公司的LTC4307如圖2所示:LTC4307是一個(gè)雙向的I2C總線(xiàn)緩沖器,并且具有I2C總線(xiàn)死鎖恢復的功能。LTC4307總線(xiàn)輸人側連接主設備,總線(xiàn)輸出側連接所有從設備。當LTC4307檢測到輸出側SDA或SCL信號被拉低30ms時(shí),就自動(dòng)斷開(kāi)I2C總線(xiàn)輸人側與輸出側的連接。并且在輸出側SCL信號上產(chǎn)生16個(gè)時(shí)鐘脈沖來(lái)釋放總線(xiàn)。當總線(xiàn)成功恢復后,LTC4307會(huì )再次連接輸人輸出側,使總線(xiàn)能夠正常工作。
評論