I2C作為板級(jí)串行數(shù)據(jù)總線,其規(guī)格相對(duì)簡(jiǎn)單,但調(diào)試過程中的一些細(xì)節(jié)問題容易被忽視,產(chǎn)生意想不到的時(shí)序錯(cuò)誤。寫這邊文章為了記錄我在調(diào)試I2C過程中遇到的問題,以便今后查閱并作為經(jīng)驗(yàn)與大家分享。
使用MCU等SoC芯片中的I2C模塊,一般不會(huì)出現(xiàn)問題,因?yàn)殛P(guān)于I2C的操作時(shí)序都經(jīng)過芯片設(shè)計(jì)公司封裝成功能完好的IP。但通過GPIO來模擬I2C操作時(shí),所有的時(shí)序需由用戶自己把握,因此,對(duì)于I2C的時(shí)序和操作要有深刻的認(rèn)識(shí)。以下是使用GPIO模擬I2C調(diào)試時(shí)需要重點(diǎn)關(guān)注的問題:
(2)I2C總線信號(hào)引腳上拉。I2C總線空閑時(shí),信號(hào)線需處于高電平狀態(tài),總線無(wú)驅(qū)動(dòng)時(shí)由電阻上拉到電源。MCU或其他SoC芯片可以使能內(nèi)部上拉或使用外部電阻上拉。
(3)SCL時(shí)鐘速度。標(biāo)準(zhǔn)速度SCL通常為100KHz,高速SCL可達(dá)400KHz,根據(jù)I2C設(shè)備時(shí)鐘特性,調(diào)試時(shí)需合理設(shè)置delay time。
(4)SDA數(shù)據(jù)線釋放(取消驅(qū)動(dòng))。I2C總線的SDA是單工雙向的數(shù)據(jù)線,同一時(shí)間只能由一方提供驅(qū)動(dòng)(主機(jī)或是設(shè)備),否則會(huì)出現(xiàn)驅(qū)動(dòng)沖突,導(dǎo)致數(shù)據(jù)出錯(cuò)或時(shí)序錯(cuò)誤。以下幾種情況SDA要及時(shí)釋放: 1)主機(jī)發(fā)送1字節(jié)數(shù)據(jù),check ack之前要及時(shí)釋放SDA。主機(jī)發(fā)送數(shù)據(jù)時(shí)SDA由主機(jī)驅(qū)動(dòng),check ack時(shí)主機(jī)檢測(cè)由設(shè)備驅(qū)動(dòng)的1bit數(shù)據(jù)。如果主機(jī)驅(qū)動(dòng)SDA未及時(shí)釋放,SCL為低時(shí)產(chǎn)生沖突,SCL為高時(shí)檢測(cè)ack出錯(cuò),甚至?xí)霈F(xiàn)SCL為高時(shí)SDA的跳變產(chǎn)生錯(cuò)誤Start/Stop標(biāo)志,尤其是在主機(jī)發(fā)送數(shù)據(jù)最后1bit為高的情況下。2)主機(jī)接收1字節(jié)數(shù)據(jù)(非最后1字節(jié)),send ack之后要及時(shí)釋放SDA。主機(jī)接收數(shù)據(jù)時(shí)SDA由設(shè)備驅(qū)動(dòng),之后設(shè)備會(huì)釋放SDA,由主機(jī)驅(qū)動(dòng)SDA發(fā)送ack,發(fā)送ack之后要及時(shí)釋放SDA,驅(qū)動(dòng)權(quán)交給設(shè)備。如果主機(jī)send ack之后未及時(shí)釋放SDA,在SCL為低時(shí)產(chǎn)生驅(qū)動(dòng)沖突,SCL為高時(shí)主機(jī)采樣數(shù)據(jù)會(huì)出現(xiàn)SDA跳變產(chǎn)生錯(cuò)誤Stop標(biāo)志,尤其是在接收下一字節(jié)數(shù)據(jù)的第1bit位為高的情況下。 這種情況下調(diào)試eeprom讀寫現(xiàn)象:數(shù)據(jù)高bit位為0時(shí)讀寫正常,數(shù)據(jù)高bit位為1時(shí),讀數(shù)據(jù)全0xFF。 |
|