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