當(dāng)前位置:首頁(yè) > 嵌入式培訓(xùn) > 嵌入式學(xué)習(xí) > 講師博文 > ARM I2C波形控制
一、I2C簡(jiǎn)介
I2C總線只需要兩條線,一條SDA數(shù)據(jù)線,一條SCL時(shí)鐘線;根據(jù)這兩條線的高低電平、上升沿、下降沿就可以實(shí)現(xiàn)主機(jī)與I2C設(shè)備的通訊;其中有:
(1)I2C總線相關(guān)
傳輸開(kāi)始條件:SCL處于高電平,SDA下降沿時(shí);
傳輸接收條件:SCL處于高電平,SDA上升沿時(shí);
傳輸數(shù)據(jù):開(kāi)始傳輸后,SCL處于高電平時(shí),SDA的數(shù)據(jù)為所傳輸?shù)臄?shù)據(jù);
回應(yīng):當(dāng)傳輸完一個(gè)字節(jié)后,I2C設(shè)備需要回應(yīng)一個(gè)ACK,這樣主機(jī)才繼續(xù)發(fā)送;因此回應(yīng)信號(hào)是在傳輸完8bit后的下一個(gè)數(shù)據(jù)位(SDA值),當(dāng)SDA為0表示有回應(yīng),為1表示沒(méi)回應(yīng);
正常I2C總線的數(shù)據(jù)是:Start + I2C device address + R/W + ACK + Data(first byte)+ ACK + ... + Data(n)+ ACK + Stop
(2)I2C設(shè)備相關(guān)
設(shè)備地址:有7位和10位兩種,具體見(jiàn)I2C設(shè)備芯片的DataSheet,由于目前用到的是7位,因此下面主要針對(duì)7位講述;在講I2C設(shè)備地址是有可能有兩種說(shuō)法,主要是用8位表示還是用7為表示,比如對(duì)于我的OLED來(lái)說(shuō),當(dāng)用8位表示時(shí)則為0x78地址,當(dāng)用7位時(shí)則為0x3c(即0x78右移1為),在驅(qū)動(dòng)中用0x78還是用0x3c要看具體平臺(tái)的I2C總線驅(qū)動(dòng),我在AMLOGIC平臺(tái)上用的是0x78,而在MV平臺(tái)上用的是0x3c;
寄存器reg:一般的I2C設(shè)備芯片都有帶reg,一般在傳輸正式的數(shù)據(jù)之前需要先傳輸reg地址,比如我的OLED來(lái)說(shuō),在傳控制命令時(shí)需要先發(fā)送0x00的reg地址,在傳輸數(shù)據(jù)時(shí)需要發(fā)送0x40的reg地址;
二、調(diào)試及波形分析
一般當(dāng)我們拿到一個(gè)I2C設(shè)備時(shí),就必須涉及到驅(qū)動(dòng)的編寫(xiě),就比如對(duì)于OLED來(lái)說(shuō),就要用編寫(xiě)OLED驅(qū)動(dòng),這樣我們才能控制它,對(duì)于OLED屏來(lái)說(shuō),第一步也是最重要的一步就是點(diǎn)亮它;當(dāng)我們做完這一步,那后面剩下的就只是細(xì)節(jié)問(wèn)題了;”萬(wàn)事開(kāi)頭難“,這句話真的不假,對(duì)于OLED來(lái)說(shuō),如何才能點(diǎn)亮,我們?cè)撛趺凑{(diào)試呢?當(dāng)我們寫(xiě)完OLED驅(qū)動(dòng),但OLED屏還是不亮,可能問(wèn)題會(huì)出現(xiàn)在哪?是硬件問(wèn)題還是軟件問(wèn)題?;若為軟件問(wèn)題,那會(huì)是I2C總線驅(qū)動(dòng)問(wèn)題,還是我們I2C設(shè)備驅(qū)動(dòng)有問(wèn)題?那么我們?cè)撊绾闻袛鄦?wèn)題出現(xiàn)位置呢?這就需要我們對(duì)I2C總線上的數(shù)據(jù)進(jìn)行分析;那么下面我將詳細(xì)講述如何獲取和分析I2C總線上的數(shù)據(jù);
(1)示波器
對(duì)于I2C總線的數(shù)據(jù),我們要用到示波器,這樣我們才能抓取到信號(hào),而且必須同時(shí)采集SDA和SCL的數(shù)據(jù);該如何抓取呢?我這邊的方式是將示波器調(diào)成邊下降沿觸發(fā)模式(因?yàn)殚_(kāi)始信號(hào)是SDA下降沿),并且設(shè)置成單次模式(這樣抓取完一次就會(huì)stop,便于我們數(shù)據(jù)分析);
(2)波形
由于我的OLED設(shè)備的地址是0x78(8位),而第一次我必須將OLED設(shè)置成off狀態(tài),通過(guò)命令表可以查到,必須發(fā)生0xAE,而剛剛有講到在發(fā)送命令前必須先發(fā)送寄存器reg地址,即0x00;于是我發(fā)送的數(shù)據(jù)為0x78+0x00+0xAE;下面是我用示波器抓取到的波形:
分析(其中黃色的為SDA信號(hào),淺藍(lán)色為SCL信號(hào)):從上述波形中我們可以讀取到數(shù)據(jù)依次是:01111000 0 00000000 101011100;即:0111100(7位OLED設(shè)備地址) + 0( 讀寫(xiě)為,0為寫(xiě),1為讀)+0(ACK回應(yīng))+00000000(寄存器reg)+ 10101110(0xAE OLED off命令);
下面當(dāng)我來(lái)隨便發(fā)送一個(gè)地址時(shí),比如當(dāng)我發(fā)送0x56(8位地址),測(cè)到的波形如下:
分析:從波形可看出數(shù)據(jù)依次為:010101101 即0101011(設(shè)備地址)+0(讀寫(xiě)位)+1(NACK無(wú)應(yīng)答),由于沒(méi)有相應(yīng)的I2C設(shè)備因此無(wú)應(yīng)答ACK信號(hào),于是就停止傳輸;
三、總結(jié)
由以上可知,可以通過(guò)查看I2C總線數(shù)據(jù)來(lái)確認(rèn)跟蹤I2C設(shè)備,已更好地確定是軟件問(wèn)題還是硬件問(wèn)題;