什么是I2C通信
?。?)I2C屬于串行通信,所有的數(shù)據(jù)以位為單位在SDA上串行傳輸
?。?)同步通信就是通信雙方工作在同一個時鐘下面,一般是通信的A方通過一根CLK線傳輸A自己的時鐘給B,B工作在A傳輸?shù)臅r鐘下。所以通信的顯著特征就是:通信中有CLK
(3)非差分:因為I2C的通信速率不高,所以使用電平信號通信,而且通信雙方距離很近,所以使用電平信號通信
?。?)低速率:I2C一般是用在同一個板子上的兩個IC之間的通信,而且用來傳輸?shù)臄?shù)據(jù)量也不大,所以本身通信速率很低(一般幾百KHz,不同的I2C芯片的通信速率可能不同,具體編程的時候要看自己所使用的設(shè)備所允許I2C的最高通信速率,不能超過這個速率)
突出特征1:主設(shè)備+從設(shè)備
?。?)I2C通信的時候,通信雙方地位是不對等的,而是分為主設(shè)備和從設(shè)備。通信由主設(shè)備發(fā)起,由主設(shè)備主導(dǎo),從設(shè)備只是按照I2C協(xié)議被動的接收主設(shè)備的通信,并及時響應(yīng)。
(2)誰是主設(shè)備,誰是從設(shè)備是由我們通信雙方來定的,I2C協(xié)議并沒有規(guī)定,一般來說一個芯片可以只做主設(shè)備,也可以只做從設(shè)備,也可以既當(dāng)主設(shè)備,也當(dāng)從設(shè)備。
突出設(shè)備2:可以多個設(shè)備同時掛在一條總線上(從設(shè)備地址)
?。?)I2C通信可以一對一(一個主設(shè)備對應(yīng)一個從設(shè)備),也可以一對多(一個主設(shè)備對應(yīng)多個從設(shè)備)
?。?)主設(shè)備來負(fù)責(zé)調(diào)度總線,決定某一時間和哪個設(shè)備從設(shè)備通信,注意:同一時間內(nèi),I2C總線只能傳輸一對設(shè)備的通用信息。所以同一時間內(nèi),只能有一個從設(shè)備和主設(shè)備通信,而其他從設(shè)備處于“”“冬眠”狀態(tài),不能出來搗亂,否則通信就會亂套。
(3)每一個I2C從設(shè)備在通信中都會有一個I2C設(shè)備地址,這個設(shè)備地址是從設(shè)備本身固有的屬性,然后通信時,主設(shè)備需要知道自己將要通信的那個設(shè)備的地址,然后在通信中通過地址來甄別是不是自己要找的那個從設(shè)備。(這個地址是一個電路板上唯一的,不是全球唯一的)
主要用途:SoC和周邊設(shè)外設(shè)之間的通信(典型的如EEPROM、電容式觸摸屏、各種sensor)
由I2C學(xué)通信時序
什么是時序?
時序:字面意思,時序就是時間順序,實際上通信中的時序就是通信線上按照時間順序發(fā)生的電平變化,以及這些變化對通信的意義就叫做時序。
I2C的總線空閑狀態(tài)、起始位、結(jié)束位?
?。?)I2C總線上有一個主設(shè)備,n(n》=1)個從設(shè)備。I2C總線上有兩種狀態(tài),空閑態(tài)(所有設(shè)備都未和主設(shè)備通信,此時總線空閑)和忙狀態(tài)(其中一個從設(shè)備在和主設(shè)備通信,此時總線被這一對占用,其他從設(shè)備必須歇著
?。?)整個通信周期分為一個周期一個周期的,兩個相鄰的通信周期是空閑態(tài)。每一個通信周期由起始位開始,一個結(jié)束位結(jié)束,中間是本周期的通信數(shù)據(jù)。
?。?)起始位不是一個時間點,而是一個時間段。這段時間的總線狀態(tài)的變化情況是:SCL線維持高電平,同時SDA線發(fā)生一個從高到低的下降沿。
(4)與起始位相似,結(jié)束位是一個時間段,在這段時間內(nèi)總線的變化情況是:SCL線維持高電平,同時SDA線發(fā)生一個低到高的上升沿。
I2C數(shù)據(jù)傳輸格式(數(shù)據(jù)位&ACK):
?。?)每一個通信周期的發(fā)起和結(jié)束都是由主設(shè)備來做,從設(shè)備只有被動的相應(yīng)主設(shè)備,沒法自己自發(fā)的去做任何事情。
(2)主設(shè)備在每個通信周期會先發(fā)8位的從設(shè)備地址(其實8位中只有7位是從設(shè)備地址,還有一位表示主設(shè)備下面是要寫入還是讀出)到總線(主設(shè)備是以廣播的形式發(fā)送,總線上的所有的從設(shè)備都能收到這個廣播),然后總線上的每個從設(shè)備都能收到這個地址,并且收到這個地址后,和自己的設(shè)備地址相比較看是否相等。如果相等說明主設(shè)備本次通信就是給我說話,如果不想等就說明本次通信與我無關(guān),不用聽不同管了。
?。?)發(fā)送方在發(fā)送了一段數(shù)據(jù)后,接收方需要回應(yīng)一個bit位,不能攜帶有效信息。只能表示2個意思(要么表示收到數(shù)據(jù),即有效響應(yīng),要么表示未接到數(shù)據(jù),即無效響應(yīng))
?。?)在某一個通信時刻,主設(shè)備和從設(shè)備只能有一個在發(fā)(占用總線,向總線寫),另一個一個在收(從總線讀),如果主設(shè)備和從設(shè)備都試圖向總線寫,那就完蛋了,通信就亂套了。
數(shù)據(jù)在總線上的傳輸協(xié)議:
?。?)I2C通信時的基本數(shù)據(jù)單位也是以字節(jié)為單位的,每次傳輸?shù)挠行?shù)據(jù)都是一個字節(jié)(8位)。
?。?)起始位及其后的8個clock中都是主設(shè)備在發(fā)送(這設(shè)備掌控總線),此時從設(shè)備只能讀取總線,通過讀取總線來得知主設(shè)備發(fā)給從設(shè)備的信息,然后到了第9個字節(jié),按照協(xié)議規(guī)定,從設(shè)備需要發(fā)送ACK給主設(shè)備,所以這設(shè)備必須釋放總線(這設(shè)備把總線置為高電平,不要動其實就類似于總線空閑狀態(tài)),同時從設(shè)備試圖拉低總線發(fā)出ACK。如果從設(shè)備拉低總線失敗,或者從設(shè)備根本沒有拉低總線,則主設(shè)備看到的現(xiàn)象就是總線在第9周期仍然一直保持高電平,這對于主設(shè)備來說,意味著我沒收到ACK信號,主設(shè)備就會認(rèn)為我剛剛發(fā)送的8字節(jié)不對(接收失?。?/p>
S5PV210的I2C控制器:
通信雙方本質(zhì)上是通過時序工作,但是時序比較復(fù)雜,不利于SoC軟件完成,因此,解決方案是SoC內(nèi)部內(nèi)置了硬件的控制器來產(chǎn)生通信時序,這樣我們寫軟件時,只需要向控制器中寫入配置值即可,控制器會產(chǎn)生適當(dāng)?shù)臅r序在通信線上和對方通信。
結(jié)構(gòu)框圖:
(1)時鐘部分,時鐘來源是PCLK_PSYS,經(jīng)過內(nèi)部分頻最終得到I2C控制器的CLK,通信中這個CLK會通過SCL線傳給從設(shè)備
?。?)I2C總線控制邏輯(前臺代表是I2CCON、I2CSTAT這兩個寄存器),主要負(fù)責(zé)I2C通信時序。實際編程中要發(fā)送起始位、停止位。ACK等都是通過這兩個寄存器(背后所代表電路模塊)實現(xiàn)的。
?。?)移位寄存器(shift regeist),將代碼中要發(fā)送的字節(jié)數(shù)據(jù),通過寄存器變成一個位一個位的丟給SDA線上去發(fā)送/接收。學(xué)過數(shù)字電路的同學(xué)應(yīng)該對寄存器不陌生
?。?)地址寄存器+比較器。本I2C控制器做從設(shè)備的時候用。
系統(tǒng)分析I2C的時鐘:
I2C時鐘源于PCL (PCLK_PSYS、等于65MHZ),經(jīng)過了2級分頻后得到的
第一級分頻是I2CCON的bit,可以得到一個中間時鐘I2CCLK(等同于PCL/16、PCLK/512)
第二級分頻是得到I2C控制器工作的時鐘,以I2CCLK這個中間時鐘為源,分頻系統(tǒng)位[1,16]
最終要得到時鐘是2級分頻后的時鐘
主要寄存器I2CCON、I2CSTAT、I2CADD、I2CDS:
I2CCON+I2CSTAT:主要用來產(chǎn)生通信時序和I2C接口設(shè)置
I2CADD:用來寫自己的slave address
I2CDS:發(fā)送/接收的數(shù)據(jù)都放在這里
I2C通信協(xié)議
1.I2C設(shè)備都有設(shè)備地址,可以多對多(多個主設(shè)備,多個從設(shè)備)
一對多:這種比較常見(我還沒遇到過多對多,手動滑稽),也不會有太多問題
多對多:需要確保時鐘(SCL)同步
2.SCL時鐘速率不要高于從設(shè)備
數(shù)據(jù)傳輸步驟如下:
1.開始條件:SDA為高電平(1),SCL為高電平時(1),SDA由高向低跳變(下降沿)
2.發(fā)送數(shù)據(jù):8個數(shù)據(jù)位,先傳最高位(MSB),然后釋放SDA線(1)(拉高電平)
SCL為低電平時(0),SDA可進(jìn)行電平轉(zhuǎn)換;
SCL為高電平時(1),SDA保持不變,接收設(shè)備(主設(shè)備或從設(shè)備)讀取數(shù)據(jù)。
3.接收響應(yīng):ACK,在第九個周期(可以說是第九個數(shù)據(jù)位)
接收設(shè)備拉低SDA(0);
答復(fù)發(fā)送設(shè)備,接收完成;
4.結(jié)束條件:SDA為低電平(0),SCL為高電平時(1),SDA由低向高跳變(上升沿)
5.重復(fù)開始條件:master需要在一次通信中進(jìn)行多次消息交換(例如與不同的slave傳輸消息,或切換讀寫操作)
開始和結(jié)束不一一對應(yīng),可以發(fā)送多次開始條件,然后只有一個結(jié)束條件
a. 主設(shè)備發(fā)送地址幀(地址+寫),發(fā)送要讀取的寄存器地址(如0xA0)
b. 主設(shè)備發(fā)送地址幀(地址+讀),接收(0xA0)寄存器數(shù)據(jù)
6.時鐘拉伸(clock stretching):
有時候,低速slave可能由于上一個請求還沒處理完,尚無法繼續(xù)接收master的后續(xù)請求,即master的數(shù)據(jù)傳輸速率超過了slave的處理能力。這種情況下,slave可以進(jìn)行時鐘拉伸來要求master暫停傳輸數(shù)據(jù) —— 通常時鐘都是由master提供的,slave只是在SDA上放數(shù)據(jù)或讀數(shù)據(jù)。
而時鐘拉伸則是slave在master釋放SCL后,將SCL主動拉低并保持,此時要求master停止在SCL上產(chǎn)生脈沖以及在SDA上發(fā)送數(shù)據(jù),直到slave釋放SCL(SCL為高電平)。之后,master便可以繼續(xù)正常的數(shù)據(jù)傳輸了??梢姇r鐘拉伸實際上是利用了時鐘同步的機(jī)制,只是時鐘由slave產(chǎn)生。
如果系統(tǒng)中存在這種低速slave并且slave實現(xiàn)了clock stretching,則master必須實現(xiàn)為能夠處理這種情況,實際上大部分slave設(shè)備中不包含SCL驅(qū)動器的,因此無法拉伸時鐘。
所以更完整的I2C數(shù)據(jù)傳輸時序圖為:
傳輸詳細(xì)內(nèi)容
1.地址幀(address frame):(用于master指明消息發(fā)往哪個slave)
地址幀:7個地址位+1個讀寫位(0寫1讀),也支持10bit地址
地址位:確保芯片Datasheet給的是幾位地址位,有的給的7位,有的給的8位(需要左移);直接給地址幀,帶讀/寫
10bit地址幀:b1111 0XX(W/R)+bXXXX XXXX;
如下圖所示
2.數(shù)據(jù)幀(data frames): 由master發(fā)往slave的數(shù)據(jù)(或由slave發(fā)往master),每一幀是8-bit的數(shù)據(jù)
3.根據(jù) (1地址幀) 的讀寫位,確定發(fā)送/接收設(shè)備
寫:和發(fā)送地址幀一樣,主設(shè)備(發(fā)送),從設(shè)備(接收);
讀:反過來,主設(shè)備(接收),從設(shè)備(發(fā)送);
后續(xù)的數(shù)據(jù)傳輸中,發(fā)送設(shè)備發(fā)送數(shù)據(jù),接收設(shè)備需要發(fā)送ACK。
責(zé)任編輯:YYX
精彩閱讀推薦:
評論
查看更多