一文搞懂I2C總線通信
本來不打算寫這篇文章,因?yàn)榫W(wǎng)上關(guān)于I2C總線通信的資料很多很全。但是最近剛換工作,主要做驅(qū)動(dòng)開發(fā),第一個(gè)驅(qū)動(dòng)就是I2C通信,想了想還是結(jié)合網(wǎng)上的資料再整理下思路,方便今后的查閱和溫習(xí)。
1
簡介
I2C(集成電路總線),由Philips公司(2006年遷移到NXP)在1980年代初開發(fā)的一種簡單、雙線雙向的同步串行總線,它利用一根時(shí)鐘線和一根數(shù)據(jù)線在連接總線的兩個(gè)器件之間進(jìn)行信息的傳遞,為設(shè)備之間數(shù)據(jù)交換提供了一種簡單高效的方法。每個(gè)連接到總線上的器件都有唯一的地址,任何器件既可以作為主機(jī)也可以作為從機(jī),但同一時(shí)刻只允許有一個(gè)主機(jī)。
I2C 標(biāo)準(zhǔn)是一個(gè)具有沖突檢測機(jī)制和仲裁機(jī)制的真正意義上的多主機(jī)總線,它能在多個(gè)主機(jī)同時(shí)請(qǐng)求控制總線時(shí)利用仲裁機(jī)制避免數(shù)據(jù)沖突并保護(hù)數(shù)據(jù)。作為嵌入式開發(fā)者,使用I2C總線通信的場景有很多,例如驅(qū)動(dòng)FRAM、E2PROM、傳感器等。
總結(jié)來說,I2C總線具有以下特點(diǎn):
只需要SDA、SCL兩條總線;
沒有嚴(yán)格的波特率要求;
所有組件之間都存在簡單的主/從關(guān)系,連接到總線的每個(gè)設(shè)備均可通過唯一地址進(jìn)行軟件尋址;
I2C是真正的多主設(shè)備總線,可提供仲裁和沖突檢測;
傳輸速度分為四種模式:
標(biāo)準(zhǔn)模式(Standard Mode):100 Kbps
快速模式(Fast Mode):400 Kbps
高速模式(High speed mode):3.4 Mbps
超快速模式(Ultra fast mode):5 Mbps
最大主設(shè)備數(shù):
無限制;
最大從機(jī)數(shù):
理論上是127。
2
物理特性
I2C 總線使用連接設(shè)備的"SDA"(串行數(shù)據(jù)總線)和"SCL"(串行時(shí)鐘總線)來傳送信息。
I2C 總線內(nèi)部使用漏極開路輸出驅(qū)動(dòng)器,因此SDA和SCL可以被拉低為低電平,但是不能被驅(qū)動(dòng)為高電平,所以每條線上都要使用一個(gè)上拉電阻,默認(rèn)情況下將其保持在高電平。
I2C 總線上拉電阻阻值取決于系統(tǒng)應(yīng)用,TI 官方手冊(cè)推薦使用以下公式來計(jì)算上拉電阻值:
根據(jù)上表,這里不難發(fā)現(xiàn)需要在做電阻選擇需要滿足幾個(gè)條件:
灌電流最大值為3mA;
低電平輸出電壓設(shè)置了最大值為0.4V。
所以根據(jù)上述公式可以計(jì)算,對(duì)于5V的電源,每個(gè)上拉電阻阻值至少1.53kΩ,而對(duì)于3.3V的電源,每個(gè)電阻阻值至少967Ω。
如果覺得計(jì)算電阻值比較麻煩,也可以使用典型值 4.7kΩ。若各位想了解更多可直接參見手冊(cè)說明。
3
通訊時(shí)序
通常情況下,一個(gè)完整的I2C通信過程包括以下 4 部分:
開始條件
地址傳送
數(shù)據(jù)傳送
停止條件
主機(jī)在 SCL 線上輸出串行時(shí)鐘信號(hào),數(shù)據(jù)在 SDA 線上進(jìn)行傳輸,每傳輸一個(gè)字節(jié)(最高位 MSB 開始傳輸)后面跟隨一個(gè)應(yīng)答位,一個(gè) SCL 時(shí)鐘脈沖傳輸一個(gè)數(shù)據(jù)位。
標(biāo)準(zhǔn)的I2C時(shí)序如下圖所示:
3.1、開始和停止條件
當(dāng)總線上的主機(jī)都不驅(qū)動(dòng)總線,總線進(jìn)入空閑狀態(tài),SCL 和 SDA 都為高電平。總線空閑狀態(tài)下總線上設(shè)備都可以通過發(fā)送開始條件啟動(dòng)通信。
當(dāng) SCL 線為高時(shí),SDA 線上出現(xiàn)由高到低的信號(hào),表明總線上產(chǎn)生了起始信號(hào)。SDA 線上出現(xiàn)由低到高的信號(hào),表明總線上產(chǎn)生了停止信號(hào),如下圖所示:
當(dāng)兩個(gè)起始信號(hào)之間沒有停止信號(hào)時(shí),即產(chǎn)生了重復(fù)起始信號(hào)。主機(jī)采用這種方法與另一個(gè)從機(jī)或相同的從機(jī)以不同傳輸方向進(jìn)行通信(例如:從寫入設(shè)備到從設(shè)備讀出)而不釋放總線。如下圖所示:
3.2、地址傳送
開始條件或者重新開始條件后面的幀是地址幀(一個(gè)字節(jié)),用于指定主機(jī)通信的對(duì)象地址,在發(fā)送停止條件之前,指定的從機(jī)一直有效。
I2C通訊支持:7 位尋址和10 位尋址兩種模式。
7 位尋址模式,地址幀(8bit)的高 7 位為從機(jī)地址,地址幀第 8 位來決定數(shù)據(jù)幀傳送的方向:7 位從機(jī)地址 + 1位讀/寫位,讀/寫位控制從機(jī)的數(shù)據(jù)傳輸方向(0:寫;1:讀)。幀格式如下所示:
10 位尋址模式,主機(jī)發(fā)送幀,第一幀發(fā)送頭序列(11110XX0,其中 XX 表示 10 位地址的高兩位),然后第二幀發(fā)送低八位從機(jī)地址。主機(jī)接收幀,第一幀發(fā)送頭序列(11110XX0,其中 XX 表示 10 位地址的高兩位),然后第二幀發(fā)送低八位從機(jī)地址。接下來會(huì)發(fā)送一個(gè)重新開始條件,然后再發(fā)送一幀頭序列(11110XX1,其中 XX 表示 10 位地址的高兩位)幀格式如下所示:
解析如下:
S :表示開始條件;
SLA :表示從機(jī)地址;
R/W#:表示發(fā)送和接收的方向。當(dāng) R/W# 為“1” 時(shí),將數(shù)據(jù)從從機(jī)發(fā)送到主機(jī);當(dāng) R/W#為“0” 時(shí),將數(shù)據(jù)從主機(jī)發(fā)送到從機(jī);
Sr :表示重新開始條件;
DATA :表示發(fā)送和接收的數(shù)據(jù);
P :表示停止條件。
3.3、數(shù)據(jù)傳送
地址匹配一致后,總線上的主機(jī)根據(jù) R/W 定義的方向一幀一幀的傳送數(shù)據(jù)。所有的地址幀后傳送的數(shù)據(jù)都視為數(shù)據(jù)幀。即使是 10 位地址格式的低 8 位地址也視為數(shù)據(jù)幀。
數(shù)據(jù)幀的長度是 8 位。SCL 的低電平 SDA 變化,SCL 的高電平 SDA 保持,每個(gè)時(shí)鐘周期發(fā)送一位數(shù)據(jù)。數(shù)據(jù)幀后的第 9 個(gè)時(shí)鐘是應(yīng)答位,是接收方向發(fā)送方傳送的握手信號(hào)。
如果總線上從機(jī)接收數(shù)據(jù),在第 9 個(gè)時(shí)鐘周期不響應(yīng)主機(jī),從機(jī)必須發(fā)送 NACK。如果總線上主機(jī)接收數(shù)據(jù),第 9 個(gè)周期發(fā)送 NACK,從機(jī)接收到 NACK,從機(jī)停止發(fā)送數(shù)據(jù)。
無論主機(jī)還是從機(jī)發(fā)送了 NACK,數(shù)據(jù)傳送終止。主機(jī)可以做下列任一動(dòng)作:
發(fā)送停止條件釋放總線 ;
發(fā)送重新開始條件開始一個(gè)新的通信。
以華大MCU(HC3F4A0系列)為例,在主機(jī)接收模式中,主機(jī)輸出 SCL 時(shí)鐘,接收從機(jī)數(shù)據(jù)并返回應(yīng)答。主機(jī)接收數(shù)據(jù)的運(yùn)行時(shí)序例如下圖所示:
7 位地址格式的主機(jī)發(fā)送數(shù)據(jù)時(shí)序圖
在主機(jī)接收模式中,主機(jī)輸出 SCL 時(shí)鐘,接收從機(jī)數(shù)據(jù)并返回應(yīng)答。主機(jī)接收數(shù)據(jù)的運(yùn)行時(shí)序例如下圖所示:
7 位地址格式的主機(jī)接收數(shù)據(jù)的時(shí)序圖
在從機(jī)發(fā)送模式中,接收來自主機(jī)的 SCL 時(shí)鐘,本產(chǎn)品為從機(jī)發(fā)送數(shù)據(jù),并且接收主機(jī)返回應(yīng)答。從機(jī)發(fā)送數(shù)據(jù)的運(yùn)行時(shí)序例如下圖所示:
7 位地址格式的從機(jī)發(fā)送模式時(shí)序圖
在從機(jī)接收模式中,接收來自主機(jī)的 SCL 時(shí)鐘和數(shù)據(jù),接收完數(shù)據(jù)后返回應(yīng)答。從機(jī)接收數(shù)據(jù)的運(yùn)行時(shí)序例如下圖所示:
7 位地址格式從機(jī)接收模式時(shí)序圖
3.4、總線應(yīng)答
每傳輸一個(gè)字節(jié),后面跟隨一個(gè)應(yīng)答位。通過將 SDA 線拉低,來允許接收端回應(yīng)發(fā)送端。ACK 為一個(gè)低電平信號(hào),當(dāng)時(shí)鐘信號(hào)為高時(shí),SDA 保持低電平則表明接收端已成功接收到發(fā)送端的數(shù)據(jù)。
當(dāng)主機(jī)作為發(fā)送器件時(shí),如果從機(jī)上產(chǎn)生無響應(yīng)信號(hào)(NACK),主機(jī)可以產(chǎn)生停止信號(hào)來退出數(shù)據(jù)傳輸,或者產(chǎn)生重復(fù)起始信號(hào)開始新一輪的數(shù)據(jù)傳輸。當(dāng)主機(jī)作為接收器件時(shí),發(fā)生無響應(yīng)信號(hào)(NACK),從機(jī)釋放 SDA 線,使主機(jī)產(chǎn)生停止信號(hào)或重復(fù)起始信號(hào)。
I2C 總線上應(yīng)答信號(hào)
3.5、總線仲裁
I2C 總線上的仲裁分為兩個(gè)部分:SCL 線上的同步和 SDA 線上的仲裁。
SCL 線上的同步(時(shí)鐘同步)
由于 I2C 總線具有線“與”的邏輯功能,SCL 線上只要有一個(gè)節(jié)點(diǎn)發(fā)送低電平,總線上就表現(xiàn)低電平。當(dāng)所有的節(jié)點(diǎn)都發(fā)送高電平時(shí),總線才能表現(xiàn)為高電平。所以,時(shí)鐘低電平的時(shí)間由時(shí)鐘電平期最長的器件決定,而時(shí)鐘的高電平時(shí)間由時(shí)鐘高電平期最短的器件決定。
由于 I2C 這種特性,當(dāng)多個(gè)主機(jī)同時(shí)發(fā)送時(shí)鐘信號(hào)時(shí),在總線上表示的是統(tǒng)一的時(shí)鐘信號(hào)。如果從機(jī)希望主機(jī)降低傳送速度可以通過將 SCL 主動(dòng)拉低延長其低電平時(shí)間來通知主機(jī),當(dāng)主機(jī)在準(zhǔn)備下一次傳送時(shí)發(fā)現(xiàn) SCL 的電平被拉低時(shí)進(jìn)行等待,直到從機(jī)完成操作并釋放 SCL 線的控制權(quán)。
SDA 線上的仲裁
SDA 線上的仲裁也是由于 I2C 總線具有線“與”的邏輯功能。主機(jī)在發(fā)送數(shù)據(jù)后,通過比較總線上的數(shù)據(jù)來決定是否退出競爭。丟失仲裁的主機(jī)立即切換到未被尋址的從機(jī)狀態(tài),以確保自身能被仲裁勝利的主機(jī)尋址到。仲裁失敗的主機(jī)繼續(xù)輸出時(shí)鐘脈沖(在 SCL 上),直到發(fā)送完當(dāng)前的串行字節(jié)。通過這種原理可以保證 I2C 總線在多個(gè)主機(jī)企圖控制總線時(shí)保證數(shù)據(jù)的不丟失。
I2C 總線上的仲裁
解析如下:
(1)另一器件發(fā)送串行數(shù)據(jù);
(2)另一器件通過拉低 SDA 先撤消了該 I2C 主機(jī)發(fā)送的一個(gè)邏輯 1(虛線)。仲裁丟失,I2C 進(jìn)入從接收模式;
(3)此時(shí) I2C 處于從接收模式,但仍產(chǎn)生時(shí)鐘脈沖,直至發(fā)送完當(dāng)前字節(jié)。I2C 將不為下個(gè)字節(jié)的傳輸產(chǎn)生時(shí)鐘脈沖。一旦贏得仲裁,SDA 上的數(shù)據(jù)傳輸由新的主機(jī)來啟動(dòng)。
4
工作過程
最后整體敘述一下I2C通訊過程,本小節(jié)內(nèi)容整理來源于:微信公眾號(hào):小麥大叔,作者菜刀和小麥。
第1步:起始條件
主設(shè)備通過將SDA線從高電平切換到低電平,再將SCL線從高電平切換到低電平,來向每個(gè)連接的從機(jī)發(fā)送啟動(dòng)條件,如下圖所示:
第2步:發(fā)送從設(shè)備地址
主設(shè)備向每個(gè)從機(jī)發(fā)送要與之通信的從機(jī)的7位或10位地址,以及相應(yīng)的讀/寫位,如下圖所示:
第3步:接收應(yīng)答
每個(gè)從設(shè)備將主設(shè)備發(fā)送的地址與其自己的地址進(jìn)行比較。如果地址匹配,則從設(shè)備通過將SDA線拉低一位以表示返回一個(gè)ACK位。
如果來自主設(shè)備的地址與從機(jī)自身的地址不匹配,則從設(shè)備將SDA線拉高,表示返回一個(gè)NACK位。
第4步:收發(fā)數(shù)據(jù)
主設(shè)備發(fā)送或接收數(shù)據(jù)到從設(shè)備,如下圖所示:
第5步:接收應(yīng)答
在傳輸完每個(gè)數(shù)據(jù)幀后,接收設(shè)備將另一個(gè)ACK位返回給發(fā)送方,以確認(rèn)已成功接收到該幀,如下圖所示:
第6步:停止通信
為了停止數(shù)據(jù)傳輸,主設(shè)備將SCL切換為高電平,然后再將SDA切換為高電平,從而向從機(jī)發(fā)送停止條件,如下圖所示:
4.1、單個(gè)主設(shè)備連接多個(gè)從機(jī)
I2C總線上的主設(shè)備使用7位地址對(duì)從設(shè)備進(jìn)行尋址,可以使用128(2的7次方)個(gè)從機(jī)地址,如下圖所示:
4.2、多個(gè)主設(shè)備連接多個(gè)從機(jī)
多個(gè)主設(shè)備可以連接到一個(gè)或多個(gè)從機(jī)。
當(dāng)兩個(gè)主設(shè)備試圖通過SDA線路同時(shí)發(fā)送或接收數(shù)據(jù)時(shí),同一系統(tǒng)中的多個(gè)主設(shè)備就會(huì)出現(xiàn)問題。
為了解決這個(gè)問題,每個(gè)主設(shè)備都需要在發(fā)送消息之前檢測SDA線是低電平還是高電平:
如果SDA線為低電平,則意味著另一個(gè)主設(shè)備可以控制總線,并且主設(shè)備應(yīng)等待發(fā)送消息;
如果SDA線為高電平,則可以安全地發(fā)送消息。
*博客內(nèi)容為網(wǎng)友個(gè)人發(fā)布,僅代表博主個(gè)人觀點(diǎn),如有侵權(quán)請(qǐng)聯(lián)系工作人員刪除。
LCD顯示屏相關(guān)文章:lcd顯示屏原理
模數(shù)轉(zhuǎn)換器相關(guān)文章:模數(shù)轉(zhuǎn)換器工作原理
塵埃粒子計(jì)數(shù)器相關(guān)文章:塵埃粒子計(jì)數(shù)器原理 lcd相關(guān)文章:lcd原理