一文搞懂I2C總線通信
本來不打算寫這篇文章,因為網(wǎng)上關于I2C總線通信的資料很多很全。但是最近剛換工作,主要做驅(qū)動開發(fā),第一個驅(qū)動就是I2C通信,想了想還是結(jié)合網(wǎng)上的資料再整理下思路,方便今后的查閱和溫習。
1
簡介
I2C(集成電路總線),由Philips公司(2006年遷移到NXP)在1980年代初開發(fā)的一種簡單、雙線雙向的同步串行總線,它利用一根時鐘線和一根數(shù)據(jù)線在連接總線的兩個器件之間進行信息的傳遞,為設備之間數(shù)據(jù)交換提供了一種簡單高效的方法。每個連接到總線上的器件都有唯一的地址,任何器件既可以作為主機也可以作為從機,但同一時刻只允許有一個主機。
I2C 標準是一個具有沖突檢測機制和仲裁機制的真正意義上的多主機總線,它能在多個主機同時請求控制總線時利用仲裁機制避免數(shù)據(jù)沖突并保護數(shù)據(jù)。作為嵌入式開發(fā)者,使用I2C總線通信的場景有很多,例如驅(qū)動FRAM、E2PROM、傳感器等。
總結(jié)來說,I2C總線具有以下特點:
只需要SDA、SCL兩條總線;
沒有嚴格的波特率要求;
所有組件之間都存在簡單的主/從關系,連接到總線的每個設備均可通過唯一地址進行軟件尋址;
I2C是真正的多主設備總線,可提供仲裁和沖突檢測;
傳輸速度分為四種模式:
標準模式(Standard Mode):100 Kbps
快速模式(Fast Mode):400 Kbps
高速模式(High speed mode):3.4 Mbps
超快速模式(Ultra fast mode):5 Mbps
最大主設備數(shù):
無限制;
最大從機數(shù):
理論上是127。
2
物理特性
I2C 總線使用連接設備的"SDA"(串行數(shù)據(jù)總線)和"SCL"(串行時鐘總線)來傳送信息。

I2C 總線內(nèi)部使用漏極開路輸出驅(qū)動器,因此SDA和SCL可以被拉低為低電平,但是不能被驅(qū)動為高電平,所以每條線上都要使用一個上拉電阻,默認情況下將其保持在高電平。

I2C 總線上拉電阻阻值取決于系統(tǒng)應用,TI 官方手冊推薦使用以下公式來計算上拉電阻值:


根據(jù)上表,這里不難發(fā)現(xiàn)需要在做電阻選擇需要滿足幾個條件:
灌電流最大值為3mA;
低電平輸出電壓設置了最大值為0.4V。
所以根據(jù)上述公式可以計算,對于5V的電源,每個上拉電阻阻值至少1.53kΩ,而對于3.3V的電源,每個電阻阻值至少967Ω。
如果覺得計算電阻值比較麻煩,也可以使用典型值 4.7kΩ。若各位想了解更多可直接參見手冊說明。
3
通訊時序
通常情況下,一個完整的I2C通信過程包括以下 4 部分:
開始條件
地址傳送
數(shù)據(jù)傳送
停止條件
主機在 SCL 線上輸出串行時鐘信號,數(shù)據(jù)在 SDA 線上進行傳輸,每傳輸一個字節(jié)(最高位 MSB 開始傳輸)后面跟隨一個應答位,一個 SCL 時鐘脈沖傳輸一個數(shù)據(jù)位。
標準的I2C時序如下圖所示:

3.1、開始和停止條件
當總線上的主機都不驅(qū)動總線,總線進入空閑狀態(tài),SCL 和 SDA 都為高電平??偩€空閑狀態(tài)下總線上設備都可以通過發(fā)送開始條件啟動通信。
當 SCL 線為高時,SDA 線上出現(xiàn)由高到低的信號,表明總線上產(chǎn)生了起始信號。SDA 線上出現(xiàn)由低到高的信號,表明總線上產(chǎn)生了停止信號,如下圖所示:

當兩個起始信號之間沒有停止信號時,即產(chǎn)生了重復起始信號。主機采用這種方法與另一個從機或相同的從機以不同傳輸方向進行通信(例如:從寫入設備到從設備讀出)而不釋放總線。如下圖所示:

3.2、地址傳送
開始條件或者重新開始條件后面的幀是地址幀(一個字節(jié)),用于指定主機通信的對象地址,在發(fā)送停止條件之前,指定的從機一直有效。
I2C通訊支持:7 位尋址和10 位尋址兩種模式。
7 位尋址模式,地址幀(8bit)的高 7 位為從機地址,地址幀第 8 位來決定數(shù)據(jù)幀傳送的方向:7 位從機地址 + 1位讀/寫位,讀/寫位控制從機的數(shù)據(jù)傳輸方向(0:寫;1:讀)。幀格式如下所示:
10 位尋址模式,主機發(fā)送幀,第一幀發(fā)送頭序列(11110XX0,其中 XX 表示 10 位地址的高兩位),然后第二幀發(fā)送低八位從機地址。主機接收幀,第一幀發(fā)送頭序列(11110XX0,其中 XX 表示 10 位地址的高兩位),然后第二幀發(fā)送低八位從機地址。接下來會發(fā)送一個重新開始條件,然后再發(fā)送一幀頭序列(11110XX1,其中 XX 表示 10 位地址的高兩位)幀格式如下所示:
解析如下:
S :表示開始條件;
SLA :表示從機地址;
R/W#:表示發(fā)送和接收的方向。當 R/W# 為“1” 時,將數(shù)據(jù)從從機發(fā)送到主機;當 R/W#為“0” 時,將數(shù)據(jù)從主機發(fā)送到從機;
Sr :表示重新開始條件;
DATA :表示發(fā)送和接收的數(shù)據(jù);
P :表示停止條件。
3.3、數(shù)據(jù)傳送
地址匹配一致后,總線上的主機根據(jù) R/W 定義的方向一幀一幀的傳送數(shù)據(jù)。所有的地址幀后傳送的數(shù)據(jù)都視為數(shù)據(jù)幀。即使是 10 位地址格式的低 8 位地址也視為數(shù)據(jù)幀。
數(shù)據(jù)幀的長度是 8 位。SCL 的低電平 SDA 變化,SCL 的高電平 SDA 保持,每個時鐘周期發(fā)送一位數(shù)據(jù)。數(shù)據(jù)幀后的第 9 個時鐘是應答位,是接收方向發(fā)送方傳送的握手信號。

如果總線上從機接收數(shù)據(jù),在第 9 個時鐘周期不響應主機,從機必須發(fā)送 NACK。如果總線上主機接收數(shù)據(jù),第 9 個周期發(fā)送 NACK,從機接收到 NACK,從機停止發(fā)送數(shù)據(jù)。
無論主機還是從機發(fā)送了 NACK,數(shù)據(jù)傳送終止。主機可以做下列任一動作:
發(fā)送停止條件釋放總線 ;
發(fā)送重新開始條件開始一個新的通信。
以華大MCU(HC3F4A0系列)為例,在主機接收模式中,主機輸出 SCL 時鐘,接收從機數(shù)據(jù)并返回應答。主機接收數(shù)據(jù)的運行時序例如下圖所示:

7 位地址格式的主機發(fā)送數(shù)據(jù)時序圖
在主機接收模式中,主機輸出 SCL 時鐘,接收從機數(shù)據(jù)并返回應答。主機接收數(shù)據(jù)的運行時序例如下圖所示:

7 位地址格式的主機接收數(shù)據(jù)的時序圖
在從機發(fā)送模式中,接收來自主機的 SCL 時鐘,本產(chǎn)品為從機發(fā)送數(shù)據(jù),并且接收主機返回應答。從機發(fā)送數(shù)據(jù)的運行時序例如下圖所示:

7 位地址格式的從機發(fā)送模式時序圖
在從機接收模式中,接收來自主機的 SCL 時鐘和數(shù)據(jù),接收完數(shù)據(jù)后返回應答。從機接收數(shù)據(jù)的運行時序例如下圖所示:

7 位地址格式從機接收模式時序圖
3.4、總線應答
每傳輸一個字節(jié),后面跟隨一個應答位。通過將 SDA 線拉低,來允許接收端回應發(fā)送端。ACK 為一個低電平信號,當時鐘信號為高時,SDA 保持低電平則表明接收端已成功接收到發(fā)送端的數(shù)據(jù)。
當主機作為發(fā)送器件時,如果從機上產(chǎn)生無響應信號(NACK),主機可以產(chǎn)生停止信號來退出數(shù)據(jù)傳輸,或者產(chǎn)生重復起始信號開始新一輪的數(shù)據(jù)傳輸。當主機作為接收器件時,發(fā)生無響應信號(NACK),從機釋放 SDA 線,使主機產(chǎn)生停止信號或重復起始信號。

I2C 總線上應答信號
3.5、總線仲裁
I2C 總線上的仲裁分為兩個部分:SCL 線上的同步和 SDA 線上的仲裁。
SCL 線上的同步(時鐘同步)
由于 I2C 總線具有線“與”的邏輯功能,SCL 線上只要有一個節(jié)點發(fā)送低電平,總線上就表現(xiàn)低電平。當所有的節(jié)點都發(fā)送高電平時,總線才能表現(xiàn)為高電平。所以,時鐘低電平的時間由時鐘電平期最長的器件決定,而時鐘的高電平時間由時鐘高電平期最短的器件決定。
由于 I2C 這種特性,當多個主機同時發(fā)送時鐘信號時,在總線上表示的是統(tǒng)一的時鐘信號。如果從機希望主機降低傳送速度可以通過將 SCL 主動拉低延長其低電平時間來通知主機,當主機在準備下一次傳送時發(fā)現(xiàn) SCL 的電平被拉低時進行等待,直到從機完成操作并釋放 SCL 線的控制權。
SDA 線上的仲裁
SDA 線上的仲裁也是由于 I2C 總線具有線“與”的邏輯功能。主機在發(fā)送數(shù)據(jù)后,通過比較總線上的數(shù)據(jù)來決定是否退出競爭。丟失仲裁的主機立即切換到未被尋址的從機狀態(tài),以確保自身能被仲裁勝利的主機尋址到。仲裁失敗的主機繼續(xù)輸出時鐘脈沖(在 SCL 上),直到發(fā)送完當前的串行字節(jié)。通過這種原理可以保證 I2C 總線在多個主機企圖控制總線時保證數(shù)據(jù)的不丟失。

I2C 總線上的仲裁
解析如下:
(1)另一器件發(fā)送串行數(shù)據(jù);
(2)另一器件通過拉低 SDA 先撤消了該 I2C 主機發(fā)送的一個邏輯 1(虛線)。仲裁丟失,I2C 進入從接收模式;
(3)此時 I2C 處于從接收模式,但仍產(chǎn)生時鐘脈沖,直至發(fā)送完當前字節(jié)。I2C 將不為下個字節(jié)的傳輸產(chǎn)生時鐘脈沖。一旦贏得仲裁,SDA 上的數(shù)據(jù)傳輸由新的主機來啟動。
4
工作過程
最后整體敘述一下I2C通訊過程,本小節(jié)內(nèi)容整理來源于:微信公眾號:小麥大叔,作者菜刀和小麥。
第1步:起始條件
主設備通過將SDA線從高電平切換到低電平,再將SCL線從高電平切換到低電平,來向每個連接的從機發(fā)送啟動條件,如下圖所示:

第2步:發(fā)送從設備地址
主設備向每個從機發(fā)送要與之通信的從機的7位或10位地址,以及相應的讀/寫位,如下圖所示:

第3步:接收應答
每個從設備將主設備發(fā)送的地址與其自己的地址進行比較。如果地址匹配,則從設備通過將SDA線拉低一位以表示返回一個ACK位。
如果來自主設備的地址與從機自身的地址不匹配,則從設備將SDA線拉高,表示返回一個NACK位。

第4步:收發(fā)數(shù)據(jù)
主設備發(fā)送或接收數(shù)據(jù)到從設備,如下圖所示:

第5步:接收應答
在傳輸完每個數(shù)據(jù)幀后,接收設備將另一個ACK位返回給發(fā)送方,以確認已成功接收到該幀,如下圖所示:

第6步:停止通信
為了停止數(shù)據(jù)傳輸,主設備將SCL切換為高電平,然后再將SDA切換為高電平,從而向從機發(fā)送停止條件,如下圖所示:

4.1、單個主設備連接多個從機
I2C總線上的主設備使用7位地址對從設備進行尋址,可以使用128(2的7次方)個從機地址,如下圖所示:

4.2、多個主設備連接多個從機
多個主設備可以連接到一個或多個從機。
當兩個主設備試圖通過SDA線路同時發(fā)送或接收數(shù)據(jù)時,同一系統(tǒng)中的多個主設備就會出現(xiàn)問題。
為了解決這個問題,每個主設備都需要在發(fā)送消息之前檢測SDA線是低電平還是高電平:
如果SDA線為低電平,則意味著另一個主設備可以控制總線,并且主設備應等待發(fā)送消息;
如果SDA線為高電平,則可以安全地發(fā)送消息。

*博客內(nèi)容為網(wǎng)友個人發(fā)布,僅代表博主個人觀點,如有侵權請聯(lián)系工作人員刪除。
LCD顯示屏相關文章:lcd顯示屏原理
模數(shù)轉(zhuǎn)換器相關文章:模數(shù)轉(zhuǎn)換器工作原理
塵埃粒子計數(shù)器相關文章:塵埃粒子計數(shù)器原理 lcd相關文章:lcd原理