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