I2C(Inter-Integrated Circuit)通信總線,作為嵌入式系統(tǒng)設(shè)計(jì)中的一個(gè)關(guān)鍵組成部分,其靈活性和高效率使其在高級(jí)應(yīng)用中備受青睞。本文旨在提供關(guān)于I2C通信總線的深度解析,包括其基本概念、特點(diǎn)、通信協(xié)議,以及在不同場(chǎng)景下的高級(jí)應(yīng)用和最佳實(shí)踐。I2C接口只有2根信號(hào)線,總線上可以連接多個(gè)設(shè)備,硬件實(shí)現(xiàn)簡(jiǎn)單,可擴(kuò)展性強(qiáng)。I2C通信協(xié)議可以用普通GPIO引腳進(jìn)行軟件模擬。I2C接口主要用于通訊速率要求不高,以及多個(gè)器件之間通信的應(yīng)用場(chǎng)景。
01
I2C總線歷史
I2C(Inter-Integrated Circuit)總線是一種重要的串行通信協(xié)議,它的歷史可以追溯到上世紀(jì)80年代初期。以下是對(duì)I2C總線歷史的詳細(xì)介紹:
起源:
I2C總線技術(shù)由荷蘭的飛利浦半導(dǎo)體(現(xiàn)在的恩智浦半導(dǎo)體)在1982年開(kāi)發(fā)。最初,這項(xiàng)技術(shù)是為了在電視機(jī)內(nèi)部實(shí)現(xiàn)簡(jiǎn)單、高效、低成本的通信而設(shè)計(jì)的。
設(shè)計(jì)目標(biāo):
設(shè)計(jì)I2C的初衷是減少電視機(jī)等復(fù)雜電子系統(tǒng)內(nèi)部的布線數(shù)量,同時(shí)也降低制造成本。通過(guò)使用只有兩根線的通信總線,它有效地減少了器件間連接的復(fù)雜性。
技術(shù)發(fā)展:
隨著技術(shù)的成熟和普及,I2C協(xié)議得到了廣泛的應(yīng)用和擴(kuò)展。從最初的標(biāo)準(zhǔn)模式(100kHz),發(fā)展到快速模式(400kHz)和高速模式(3.4MHz)。
標(biāo)準(zhǔn)化和開(kāi)放:
雖然最初由飛利浦半導(dǎo)體開(kāi)發(fā),但I(xiàn)2C協(xié)議后來(lái)被標(biāo)準(zhǔn)化并廣泛應(yīng)用于多種設(shè)備中。飛利浦半導(dǎo)體放棄了對(duì)這項(xiàng)技術(shù)的專利權(quán),使其成為開(kāi)放標(biāo)準(zhǔn)。
廣泛應(yīng)用:
I2C技術(shù)由于其簡(jiǎn)單性和有效性,已成為嵌入式系統(tǒng)設(shè)計(jì)中不可或缺的一部分。
02
I2C通信總線基本概念
I2C是一種多主機(jī)、兩線制、低速串行通信總線,廣泛用于微控制器和各種外圍設(shè)備之間的通信。它使用兩條線路:串行數(shù)據(jù)線(SDA)和串行時(shí)鐘線(SCL)進(jìn)行雙向傳輸。
特點(diǎn)
兩線制總線:I2C僅使用兩條線——串行數(shù)據(jù)線(SDA)和串行時(shí)鐘線(SCL)進(jìn)行通信,有效降低了連接復(fù)雜性。
多主多從設(shè)備支持:I2C支持多個(gè)主設(shè)備和多個(gè)從設(shè)備連接到同一總線上。每個(gè)設(shè)備都有唯一的地址。
可變的時(shí)鐘速率:I2C總線支持不同的速率模式,如標(biāo)準(zhǔn)模式(100kbps)、快速模式(400kbps)和高速模式(3.4Mbps)。
同步通信:I2C是一種同步通信協(xié)議,數(shù)據(jù)傳輸由時(shí)鐘信號(hào)(SCL)來(lái)控制。
簡(jiǎn)單的連接:I2C通信對(duì)硬件的要求比較低,很容易在微控制器和外圍設(shè)備間實(shí)現(xiàn)連接。
地址分配:每個(gè)I2C設(shè)備都通過(guò)一個(gè)7位或10位的地址來(lái)識(shí)別,這使得總線上可以連接多個(gè)設(shè)備。
阻塞傳輸:I2C支持阻塞傳輸機(jī)制,即主設(shè)備可以在傳輸過(guò)程中控制總線,防止其他設(shè)備發(fā)送數(shù)據(jù)。
應(yīng)用廣泛:由于其簡(jiǎn)單和靈活性,I2C被廣泛應(yīng)用于各種電子產(chǎn)品中,如傳感器、LCD顯示器、EEPROM等。
總線仲裁和沖突檢測(cè):在多主模式下,I2C能夠處理多個(gè)主設(shè)備同時(shí)嘗試控制總線的情況。
低功耗:I2C總線的設(shè)計(jì)使其成為低功耗的通信方式,適用于電池供電的設(shè)備。
基本特征
總線結(jié)構(gòu):
兩線制:使用兩條線進(jìn)行通信,分別是串行數(shù)據(jù)線(SDA)和串行時(shí)鐘線(SCL)。
多主多從結(jié)構(gòu):支持多個(gè)主設(shè)備和多個(gè)從設(shè)備連接到同一總線上。
通信方式:
同步串行:數(shù)據(jù)傳輸同步于時(shí)鐘信號(hào)。
字節(jié)格式:每個(gè)字節(jié)由8位數(shù)據(jù)構(gòu)成,加上開(kāi)始和停止條件以及可選的應(yīng)答位。
時(shí)鐘速率:
支持多種速率,包括標(biāo)準(zhǔn)模式(100kbps)、快速模式(400kbps)和高速模式(3.4Mbps)。
總線控制:
開(kāi)始和停止條件:通信由主設(shè)備通過(guò)在SDA線上生成特定的信號(hào)模式來(lái)開(kāi)始和結(jié)束。
地址幀:每次通信開(kāi)始時(shí),主設(shè)備發(fā)送一個(gè)地址幀來(lái)指定與之通信的從設(shè)備。
數(shù)據(jù)傳輸:
主從通信:主設(shè)備控制時(shí)鐘信號(hào),向從設(shè)備發(fā)送或接收數(shù)據(jù)。
應(yīng)答位:每個(gè)字節(jié)后,接收方
發(fā)送一個(gè)應(yīng)答位(ACK)或非應(yīng)答位(NACK),以告知發(fā)送方數(shù)據(jù)是否被成功接收。
地址和仲裁
設(shè)備地址:
7位或10位地址:每個(gè)I2C設(shè)備都有一個(gè)唯一的地址,允許在同一總線上連接多個(gè)設(shè)備。
總線仲裁:
在多主模式下,當(dāng)兩個(gè)主設(shè)備同時(shí)嘗試控制總線時(shí),I2C協(xié)議包含仲裁機(jī)制以決定哪個(gè)設(shè)備獲得控制權(quán)。
03
I2C數(shù)據(jù)傳輸流程
數(shù)據(jù)信號(hào)以8位的序列傳輸。所以在特殊的開(kāi)始條件發(fā)生后,就會(huì)出現(xiàn)第一個(gè)8位序列,它指示了數(shù)據(jù)被發(fā)送到哪個(gè)從設(shè)備的地址。每個(gè)8位序列之后都會(huì)跟隨一個(gè)稱為確認(rèn)的位。
在大多數(shù)情況下,第一個(gè)確認(rèn)位之后會(huì)跟著另一個(gè)尋址序列,但這次是針對(duì)從設(shè)備的內(nèi)部寄存器。在尋址序列之后是數(shù)據(jù)序列,直到數(shù)據(jù)完全傳輸完畢,并以一個(gè)特殊的停止條件結(jié)束。
開(kāi)始條件發(fā)生在數(shù)據(jù)線在時(shí)鐘線仍然高電平的時(shí)候變低。之后,時(shí)鐘開(kāi)始,并且在每個(gè)時(shí)鐘脈沖期間傳輸每一位數(shù)據(jù)。設(shè)備尋址序列從最重要的位開(kāi)始,以最不重要的位結(jié)束,實(shí)際上是由7位組成的,因?yàn)榈?位用于指示主設(shè)備是向從設(shè)備寫入(邏輯低)還是從中讀?。ㄟ壿嫺撸?。
下一個(gè)確認(rèn)位由從設(shè)備用來(lái)指示它是否成功接收了前一個(gè)位序列。所以這次主設(shè)備將SDA線的控制權(quán)交給從設(shè)備,如果從設(shè)備成功接收了前一個(gè)序列,它將把SDA線拉低到所謂的確認(rèn)狀態(tài)。
如果從設(shè)備沒(méi)有把SDA線拉低,這種狀態(tài)被稱為不確認(rèn),意味著它沒(méi)有成功接收前一個(gè)序列,這可能由多種原因造成。例如,從設(shè)備可能正忙,可能不理解接收到的數(shù)據(jù),或者不能再接收任何數(shù)據(jù)等等。 在這種情況下,主設(shè)備決定如何繼續(xù)操作。
接下來(lái)是內(nèi)部寄存器的尋址。內(nèi)部寄存器是從設(shè)備內(nèi)存中包含各種信息或數(shù)據(jù)的位置。
例如,ADXL345加速度計(jì)有一個(gè)獨(dú)特的設(shè)備地址和額外的內(nèi)部寄存器地址,用于X、Y和Z軸。 因此,如果我們首先想讀取x軸的數(shù)據(jù),我們需要發(fā)送設(shè)備地址,然后發(fā)送x軸的特定內(nèi)部寄存器地址。這些地址可以從傳感器的數(shù)據(jù)手冊(cè)中找到。
在尋址之后,數(shù)據(jù)傳輸序列開(kāi)始,要么來(lái)自主設(shè)備,要么來(lái)自從設(shè)備,這取決于在讀/寫位選擇的模式。
在數(shù)據(jù)完全發(fā)送之后,傳輸將以停止條件結(jié)束,當(dāng)SDA線在SCL線高電平時(shí)從低變高。這就是I2C通信協(xié)議的工作原理。
上述內(nèi)容出現(xiàn)了很多特定概念,我們下面來(lái)分別解釋他們:
SDA和SCL信號(hào)
SDA和SCL都是雙向線路,通過(guò)電流源或上拉電阻連接到正電源電壓(見(jiàn)圖3)。 當(dāng)總線空閑時(shí),兩條線路都是HIGH。連接到總線的設(shè)備的輸出級(jí)必須具有開(kāi)漏極或開(kāi)集電極來(lái)執(zhí)行有線與功能。I2C總線上的數(shù)據(jù)可以在標(biāo)準(zhǔn)模式下以高達(dá)100 kbit/s的速度傳輸,在快速模式下可達(dá)400 kbit/s,在快速模式+中可達(dá)1 Mbit/s,或在高速模式下可達(dá)3.4 Mbit/s??偩€電容限制了連接到總線的接口數(shù)量。
對(duì)于單個(gè)主應(yīng)用程序,如果總線上沒(méi)有設(shè)備會(huì)拉伸時(shí)鐘,主SCL輸出可以是推挽驅(qū)動(dòng)器設(shè)計(jì)。
數(shù)據(jù)有效性
SDA線上的數(shù)據(jù)必須在時(shí)鐘HIGH期間保持穩(wěn)定。只有當(dāng)SCL線上的時(shí)鐘信號(hào)為L(zhǎng)OW時(shí),數(shù)據(jù)線的HIGH或LOW狀態(tài)才能改變(見(jiàn)圖4)。傳輸?shù)拿總€(gè)數(shù)據(jù)位都會(huì)產(chǎn)生一個(gè)時(shí)鐘脈沖。
START和STOP條件
所有事務(wù)都以START(S)開(kāi)始,并由STOP§終止(參見(jiàn)圖5)。 SDA線上SCL為HIGH時(shí),HIGH到LOW的轉(zhuǎn)換定義了一個(gè)START條件。 SDA線上SCL為HIGH時(shí),LOW到HIGH的轉(zhuǎn)換定義了一個(gè)STOP條件。
START和STOP條件總是由主設(shè)備產(chǎn)生。在START條件之后,總線被認(rèn)為是忙碌的。在STOP條件之后的某個(gè)時(shí)間,總線被認(rèn)為是空閑的。
如果產(chǎn)生了重復(fù)的START(Sr)而不是STOP條件,總線保持忙碌。在這方面,START(S)和重復(fù)的START(Sr)條件在功能上是相同的。
因此,對(duì)于本文檔的其余部分,S符號(hào)被用作代表START和重復(fù)的START條件的通用術(shù)語(yǔ),除非Sr是特別相關(guān)的。
如果連接到總線的設(shè)備合并了必要的接口硬件,則檢測(cè)START和STOP條件是容易的。然而,沒(méi)有這種接口的微控制器必須在每個(gè)時(shí)鐘周期內(nèi)對(duì)SDA線采樣至少兩次,以感知轉(zhuǎn)換。
字節(jié)格式
每一個(gè)放在SDA線上的字節(jié)必須是8位長(zhǎng)。每次傳輸可以傳輸?shù)淖止?jié)數(shù)是沒(méi)有限制的。每一個(gè)字節(jié)后面必須跟一個(gè)確認(rèn)位。數(shù)據(jù)以最有效位(MSB)為首進(jìn)行傳輸(見(jiàn)圖6)。如果一個(gè)從機(jī)在執(zhí)行其他一些功能之前不能接收或傳輸另一個(gè)完整的字節(jié)數(shù)據(jù),例如處理一個(gè)內(nèi)部中斷,它可以保持時(shí)鐘線SCL LOW,迫使主機(jī)進(jìn)入等待狀態(tài)。當(dāng)從機(jī)準(zhǔn)備好接收另一個(gè)字節(jié)數(shù)據(jù)并釋放時(shí)鐘線SCL時(shí),數(shù)據(jù)傳輸繼續(xù)進(jìn)行。
Acknowledge(ACK)和Not Acknowledge(NACK)
確認(rèn)發(fā)生在每個(gè)字節(jié)之后。確認(rèn)位允許接收端向發(fā)送端發(fā)出信號(hào),表示字節(jié)被成功接收,可以發(fā)送另一個(gè)字節(jié)。主設(shè)備產(chǎn)生所有的時(shí)鐘脈沖,包括確認(rèn)的第九個(gè)時(shí)鐘脈沖。
確認(rèn)信號(hào)定義如下:發(fā)送端在確認(rèn)時(shí)鐘脈沖期間釋放SDA線,這樣接收端就可以拉SDA線LOW,并且在該時(shí)鐘脈沖的HIGH期間保持穩(wěn)定的LOW(參見(jiàn)圖4)。設(shè)
當(dāng)SDA在第九個(gè)時(shí)鐘脈沖期間保持HIGH時(shí),這被定義為不確認(rèn)信號(hào)。主設(shè)備然后可以產(chǎn)生一個(gè)STOP條件來(lái)中止傳輸,或者重復(fù)的START條件來(lái)啟動(dòng)一個(gè)新的傳輸。有五個(gè)條件導(dǎo)致NACK的產(chǎn)生:
沒(méi)有接收器在總線上傳輸?shù)刂?,所以沒(méi)有設(shè)備響應(yīng)確認(rèn)。
接收器無(wú)法接收或發(fā)送,因?yàn)樗趫?zhí)行一些實(shí)時(shí)功能,并且還沒(méi)有準(zhǔn)備好與主服務(wù)器進(jìn)行通信。
在傳輸過(guò)程中,接收方收到了它無(wú)法理解的數(shù)據(jù)或命令。
在傳輸過(guò)程中,接收方不能接收到任何更多的數(shù)據(jù)字節(jié)。
主接收機(jī)必須向從發(fā)送機(jī)發(fā)出傳輸結(jié)束的信號(hào)。
時(shí)鐘同步
兩個(gè)主控器可以同時(shí)在一個(gè)空閑總線上開(kāi)始傳輸,必須有一種方法來(lái)決定哪個(gè)主控器控制總線并完成傳輸。這是通過(guò)時(shí)鐘同步和仲裁來(lái)實(shí)現(xiàn)的。在單主控器系統(tǒng)中,時(shí)鐘同步和仲裁是不需要的。
時(shí)鐘同步是通過(guò)I2C接口到SCL線的有線與連接來(lái)實(shí)現(xiàn)的。這意味著SCL線上的HIGH到LOW轉(zhuǎn)換會(huì)導(dǎo)致相關(guān)的主控器開(kāi)始計(jì)數(shù)他們的LOW周期,一旦主控器時(shí)鐘變?yōu)長(zhǎng)OW,它會(huì)保持SCL線處于該狀態(tài),直到時(shí)鐘達(dá)到HIGH狀態(tài)(見(jiàn)圖7)。然而,如果另一個(gè)時(shí)鐘仍然在它的LOW周期內(nèi),這個(gè)時(shí)鐘的LOW到HIGH轉(zhuǎn)換可能不會(huì)改變SCL線的狀態(tài)。因此,SCL線被具有最長(zhǎng)LOW周期的主控器保持為L(zhǎng)OW。具有較短LOW周期的主控器在這段時(shí)間內(nèi)進(jìn)入HIGH等待狀態(tài)。
當(dāng)所有主控機(jī)都結(jié)束了低周期時(shí),SCL線釋放并變?yōu)楦唠娖?。此時(shí)主控機(jī)時(shí)鐘與SCL線的狀態(tài)沒(méi)有區(qū)別,所有主控機(jī)開(kāi)始計(jì)算它們的高周期。第一個(gè)完成高周期的主控機(jī)再次拉低SCL線。
這樣,一個(gè)同步SCL時(shí)鐘就產(chǎn)生了,它的低周期由低周期最長(zhǎng)的主控機(jī)決定,而它的高周期由高周期最短的主控機(jī)決定。
仲裁
仲裁,像同步一樣,是指只有在系統(tǒng)中使用多個(gè)主設(shè)備時(shí)才需要的協(xié)議部分。從設(shè)備不參與仲裁過(guò)程。只有總線空閑時(shí),主設(shè)備才可以開(kāi)始傳輸。兩個(gè)主設(shè)備可以在最小保持時(shí)間(tHD; STA)內(nèi)產(chǎn)生一個(gè)START條件,這會(huì)導(dǎo)致總線上產(chǎn)生一個(gè)有效的START條件。然后需要仲裁來(lái)決定哪個(gè)主設(shè)備將完成它的傳輸。
仲裁逐位進(jìn)行。在每個(gè)位期間,當(dāng)SCL為HIGH時(shí),每個(gè)主設(shè)備檢查SDA電平是否與它所發(fā)送的相匹配。這個(gè)過(guò)程可能需要許多位。兩個(gè)主設(shè)備實(shí)際上可以無(wú)誤地完成整個(gè)事務(wù),只要傳輸是相同的。第一次一個(gè)主設(shè)備試圖發(fā)送HIGH,但檢測(cè)到SDA電平為L(zhǎng)OW,主設(shè)備知道它已經(jīng)失去了仲裁并關(guān)閉SDA輸出驅(qū)動(dòng)器。另一個(gè)主設(shè)備繼續(xù)完成它的事務(wù)。
在仲裁過(guò)程中沒(méi)有信息丟失。一個(gè)失去仲裁的主設(shè)備可以產(chǎn)生時(shí)鐘脈沖,直到它失去仲裁的字節(jié)結(jié)束,并繼續(xù)產(chǎn)生時(shí)鐘脈沖。必須在總線空閑時(shí)重新開(kāi)始它的事務(wù)。
如果一個(gè)主設(shè)備也包含一個(gè)從設(shè)備功能,并且它在尋址階段失去仲裁,有可能是獲勝的主設(shè)備試圖尋址它。因此,失敗的主設(shè)備必須立即切換到它的從設(shè)備模式。
圖8顯示了兩個(gè)主設(shè)備的仲裁過(guò)程??赡苌婕案鄡?nèi)容,這取決于總線連接了多少主設(shè)備。當(dāng)產(chǎn)生DATA1的主設(shè)備的內(nèi)部數(shù)據(jù)電平與SDA線上的實(shí)際電平之間存在差異時(shí),DATA1輸出被關(guān)閉。這不影響由獲勝的主設(shè)備發(fā)起的數(shù)據(jù)傳輸。
由于I2C總線的控制完全由競(jìng)爭(zhēng)主設(shè)備發(fā)送的地址和數(shù)據(jù)決定,所以沒(méi)有中心主設(shè)備,總線上也沒(méi)有任何優(yōu)先順序。
如果仲裁程序仍在進(jìn)行,當(dāng)一個(gè)主設(shè)備發(fā)送重復(fù)的START或STOP條件,而另一個(gè)主設(shè)備仍在發(fā)送數(shù)據(jù)時(shí),則存在一個(gè)未定義的條件。換句話說(shuō),以下組合會(huì)導(dǎo)致一個(gè)未定義的條件:
主設(shè)備1發(fā)送重復(fù)的START條件,主設(shè)備2發(fā)送一個(gè)數(shù)據(jù)位。
主設(shè)備1發(fā)送STOP條件,主設(shè)備2發(fā)送一個(gè)數(shù)據(jù)位。
主設(shè)備1發(fā)送重復(fù)的START條件,主設(shè)備2發(fā)送一個(gè)STOP條件。
時(shí)鐘拉伸
時(shí)鐘拉伸通過(guò)保持SCL線LOW暫停事務(wù)。事務(wù)無(wú)法繼續(xù),直到該線再次釋放為HIGH。時(shí)鐘拉伸是可選的,事實(shí)上,大多數(shù)從設(shè)備不包括SCL驅(qū)動(dòng)程序,因此它們無(wú)法拉伸時(shí)鐘。
在字節(jié)級(jí),設(shè)備可能能夠以較快的速度接收字節(jié)數(shù)據(jù),但需要更多的時(shí)間來(lái)存儲(chǔ)接收到的字節(jié)或準(zhǔn)備傳輸另一個(gè)字節(jié)。從設(shè)備可以在接收和確認(rèn)一個(gè)字節(jié)后保持SCL線LOW,以迫使主設(shè)備進(jìn)入等待狀態(tài),直到從設(shè)備準(zhǔn)備好在一種握手過(guò)程類型中進(jìn)行下一個(gè)字節(jié)傳輸(見(jiàn)圖7)。
在位級(jí),設(shè)備如微控制器,具有或不具有I2C總線有限的硬件,可以通過(guò)延長(zhǎng)每個(gè)時(shí)鐘LOW周期來(lái)減慢總線時(shí)鐘。任何主設(shè)備的速度都適應(yīng)于該設(shè)備的內(nèi)部運(yùn)行速率。
從地址和R/W位
數(shù)據(jù)傳輸遵循圖9所示的格式。在START條件(S)之后,發(fā)送一個(gè)從地址。這個(gè)地址是7位長(zhǎng),后面跟著第八位,這是一個(gè)數(shù)據(jù)方向位(R/W)——“0”表示傳輸(WRITE),“1”表示數(shù)據(jù)請(qǐng)求(READ)(參見(jiàn)圖10)。數(shù)據(jù)傳輸總是由master生成的STOP條件§終止。然而,如果master仍然希望在總線上通信,它可以生成一個(gè)重復(fù)的START條件(Sr)并在沒(méi)有首先生成STOP條件的情況下尋址另一個(gè)從設(shè)備。在這樣的傳輸中,各種讀/寫格式的組合是可能的。
10位尋址
10位尋址擴(kuò)展了可能的地址數(shù)。具有7位和10位地址的設(shè)備可以連接到同一個(gè)I2C總線,并且7位和10位尋址都可以在所有總線速度模式下使用。目前,10位尋址還沒(méi)有被廣泛使用。 10位從屬地址是由一個(gè)START條件(S)或重復(fù)的START條件(Sr)之后的前兩個(gè)字節(jié)組成的。 第一個(gè)字節(jié)的前7位是組合1111 0XX,其中最后兩個(gè)位(XX)是10位地址的兩個(gè)最有效位(MSB);第一個(gè)字節(jié)的第八位是R/W位,它決定了消息的方向。 雖然有8個(gè)可能的保留地址位1111 XXX的組合, 但只有四個(gè)組合1111 0XX用于10位尋址。其余四個(gè)組合1111 1XX被保留用于未來(lái)的I2C總線增強(qiáng)。
所有先前描述的7位尋址的讀/寫格式組合都可能用10位尋址。這里詳細(xì)介紹兩種格式:
主發(fā)送器用一個(gè)10位從屬地址向從屬接收器發(fā)送。 傳輸方向不變(見(jiàn)圖14)。當(dāng)一個(gè)10位地址跟隨一個(gè)START條件時(shí),每個(gè)從屬比較從屬地址第一個(gè)字節(jié)的前7位(1111 0XX)與自己的地址,并測(cè)試第八位(R/W方向位)是否為0??赡苡卸鄠€(gè)設(shè)備找到一個(gè)匹配并產(chǎn)生一個(gè)確認(rèn)(A1)。所有找到匹配的從屬比較從屬地址第二個(gè)字節(jié)的八位(XXXX XXXX)與自己的地址,但只有一個(gè)從屬找到一個(gè)匹配并產(chǎn)生一個(gè)確認(rèn)(A2)。匹配的從屬仍然由主尋址,直到它接收到一個(gè)STOP條件§或重復(fù)的START條件(Sr),后面跟著一個(gè)不同的從屬地址。
主接收器用一個(gè)10位從屬地址讀取從屬發(fā)送器。 傳輸方向在第二個(gè)R/W位之后改變(圖15)。直到并包括確認(rèn)位A2,過(guò)程與前面描述的用于一個(gè)從屬發(fā)送器的程序相同。主發(fā)送器尋址從接收器。在重復(fù)的START條件(Sr)之后,匹配的從設(shè)備記住它之前被尋址過(guò)。這個(gè)從設(shè)備然后檢查Sr之后的從地址的第一個(gè)字節(jié)的前7位是否與它們?cè)赟TART條件(S)之后是相同的,并測(cè)試第八位(R/W)是否為1。 如果有匹配,從設(shè)備認(rèn)為它被作為一個(gè)發(fā)送器尋址,并產(chǎn)生確認(rèn)A3。從發(fā)送器保持尋址狀態(tài),直到它接收到一個(gè)STOP條件§或接收到另一個(gè)重復(fù)的START條件(Sr)后跟隨一個(gè)不同的從地址。在重復(fù)的START條件(Sr)之后,所有其他從設(shè)備也將比較從地址(1111 0XX)的第一個(gè)字節(jié)的前7位與它們自己的地址,并測(cè)試第八位(R/W)。 然而,它們中沒(méi)有一個(gè)被尋址,因?yàn)镽/W=1(10位設(shè)備),或者1111 0XX從地址(7位設(shè)備)不匹配。
具有10位尋址的從設(shè)備對(duì)“通用調(diào)用”的反應(yīng)與具有7位尋址的從設(shè)備相同。硬件主設(shè)備可以在“通用調(diào)用”后傳輸其10位地址。在這種情況下,“通用調(diào)用”地址字節(jié)后面跟著兩個(gè)連續(xù)的字節(jié),其中包含主發(fā)送器的10位地址。格式如圖15所示,第一個(gè)數(shù)據(jù)字節(jié)包含主地址的最低有效位8位。
開(kāi)始字節(jié)0000 0001 (01h)可以以與7位地址相同的方式出現(xiàn)在10位地址之前。
通用調(diào)用地址
通用調(diào)用地址用于同時(shí)尋址連接到I2C總線的每個(gè)設(shè)備。然而,如果一個(gè)設(shè)備不需要通用調(diào)用結(jié)構(gòu)中提供的任何數(shù)據(jù),它可以通過(guò)不發(fā)出確認(rèn)來(lái)忽略這個(gè)地址。如果一個(gè)設(shè)備確實(shí)需要來(lái)自通用調(diào)用地址的數(shù)據(jù),它會(huì)確認(rèn)這個(gè)地址并表現(xiàn)為從接收器。如果一個(gè)或多個(gè)設(shè)備響應(yīng),主設(shè)備實(shí)際上不知道有多少設(shè)備確認(rèn)。第二個(gè)字節(jié)和后續(xù)字節(jié)被每一個(gè)能夠處理此數(shù)據(jù)的從接收器確認(rèn)。一個(gè)不能處理這些字節(jié)之一的從設(shè)備必須通過(guò)不確認(rèn)來(lái)忽略它。同樣,如果一個(gè)或多個(gè)從設(shè)備確認(rèn),主設(shè)備將不會(huì)看到不確認(rèn)。通用調(diào)用地址的含義總是在第二個(gè)字節(jié)中指定(見(jiàn)圖16)。
有兩種情況需要考慮:
當(dāng)最低有效位B為“0”時(shí)。
當(dāng)最低有效位B為“1”時(shí)。
當(dāng)位B為“0”時(shí),第二個(gè)字節(jié)有以下定義:
0000 0110 (06h):硬件復(fù)位并寫入從地址的可編程部分。在接收到這個(gè)2字節(jié)序列時(shí),所有設(shè)計(jì)用于響應(yīng)通用調(diào)用地址的設(shè)備都復(fù)位并接收其地址的可編程部分。
必須采取預(yù)防措施,以確保設(shè)備在施加電源電壓后沒(méi)有拉下SDA或SCL線,因?yàn)檫@些低電平會(huì)阻塞總線。
0000 0100 (04h):硬件寫入從地址的可編程部分。 行為與上述相同,但設(shè)備不復(fù)位。
0000 0000 (00h):此代碼不允許用作第二個(gè)字節(jié)。
編程過(guò)程的序列在適當(dāng)?shù)脑O(shè)備數(shù)據(jù)表中公布。其余代碼尚未固定,設(shè)備必須忽略它們。
當(dāng)位B為“1”時(shí),2字節(jié)序列是“硬件通用調(diào)用”。這意味著該序列由硬件主設(shè)備傳輸,例如鍵盤掃描器,
它可以被編程來(lái)傳輸所需的從地址。由于硬件主設(shè)備事先并不知道消息必須被傳輸?shù)侥膫€(gè)設(shè)備,它只能生成這個(gè)硬件通用調(diào)用和它自己的地址 — 向系統(tǒng)標(biāo)識(shí)它自己(參見(jiàn)圖 17)。
第二個(gè)字節(jié)中剩下的七位包含硬件主機(jī)的地址。
這個(gè)地址被連接到總線的智能設(shè)備(例如,微控制器)識(shí)別,然后接受來(lái)自硬件主機(jī)的信息。如果硬件主機(jī)也可以充當(dāng)從機(jī),從機(jī)地址與主機(jī)地址相同。
在某些系統(tǒng)中,另一種方法是將硬件主發(fā)射機(jī)在系統(tǒng)復(fù)位后設(shè)置為從接收機(jī)模式。這樣,系統(tǒng)配置主可以告訴硬件主發(fā)射機(jī)(現(xiàn)在處于從接收機(jī)模式)必須發(fā)送數(shù)據(jù)到哪個(gè)地址(見(jiàn)圖18)。在編程程序之后,硬件主保持在主發(fā)射機(jī)模式。
開(kāi)始字節(jié)
微控制器可以以兩種方式連接到I2C總線。帶有片上硬件I2C總線接口的微控制器可以被編程為只被總線請(qǐng)求中斷。當(dāng)設(shè)備沒(méi)有這樣的接口時(shí),它必須通過(guò)軟件不斷地監(jiān)視總線。顯然,微控制器監(jiān)視或輪詢總線的次數(shù)越多,它執(zhí)行預(yù)定功能的時(shí)間就越少。
因此,在快速的硬件設(shè)備和相對(duì)較慢的依賴于軟件輪詢的微控制器之間存在速度差異。
在這種情況下,數(shù)據(jù)傳輸可以先由一個(gè)比正常情況長(zhǎng)得多的啟動(dòng)過(guò)程(見(jiàn)圖19)。啟動(dòng)過(guò)程包括:
一個(gè)開(kāi)始條件(S)
一個(gè)開(kāi)始字節(jié)(0000 0001)
一個(gè)確認(rèn)時(shí)鐘脈沖(ACK)
一個(gè)重復(fù)的開(kāi)始條件(Sr)
在需要總線訪問(wèn)的主機(jī)傳輸了START條件S之后,
傳輸START字節(jié)(0000 0001)。另一個(gè)微控制器因此可以以低采樣率對(duì)SDA線進(jìn)行采樣,直到檢測(cè)到START字節(jié)中的7個(gè)零之一。在檢測(cè)到SDA線上的LOW電平后,微控制器可以切換到更高的采樣率,以找到重復(fù)的START條件Sr,然后用于同步。
硬件接收器在接收到重復(fù)的START條件Sr后重置,因此忽略START字節(jié)。
在START字節(jié)后生成一個(gè)與確認(rèn)相關(guān)的時(shí)鐘脈沖。這只是為了符合總線上使用的字節(jié)處理格式。不允許任何設(shè)備確認(rèn)START字節(jié)。
設(shè)備ID
設(shè)備ID字段(見(jiàn)圖20)是一個(gè)可選的3字節(jié)只讀(24位)字,提供以下信息:
12位制造商名稱,每個(gè)制造商(例如NXP)都是唯一的
9位部件標(biāo)識(shí),由制造商指定(例如PCA9698)
3位模具修訂,由制造商指定(例如RevX)
設(shè)備ID是只讀的,硬連接在設(shè)備中,可以按如下方式訪問(wèn):
START 條件
主控器發(fā)送保留設(shè)備ID I2C總線地址,后面跟著設(shè)置為‘0’的R/W位(寫入):“1111 1000”。
主設(shè)備發(fā)送它必須識(shí)別的從設(shè)備的I2C總線從地址。LSB是一個(gè)“不關(guān)心”的值。只有一個(gè)設(shè)備必須確認(rèn)這個(gè)字節(jié)(具有I2C總線從地址的設(shè)備)。
主設(shè)備發(fā)送一個(gè)Re-START條件。
備注:一個(gè)STOP條件跟隨一個(gè)START條件重置從設(shè)備的狀態(tài)機(jī),設(shè)備ID讀取無(wú)法執(zhí)行。同樣,一個(gè)STOP條件或一個(gè)Re-START條件跟隨訪問(wèn)另一個(gè)從設(shè)備重置從設(shè)備的狀態(tài)機(jī),設(shè)備ID讀取無(wú)法執(zhí)行。
主控器發(fā)送保留設(shè)備ID I2C總線地址,后面跟著設(shè)置為‘1’的R/W位:‘1111 1001’。
設(shè)備ID讀取可以完成,從12個(gè)制造商位(第一個(gè)字節(jié)+第二個(gè)字節(jié)的四個(gè)MSB)開(kāi)始,接下來(lái)是9個(gè)部件識(shí)別位(第二個(gè)字節(jié)的四個(gè)LSB+第三個(gè)字節(jié)的五個(gè)MSB),然后是三個(gè)模具修正位(第三個(gè)字節(jié)的三個(gè)LSB)。
主設(shè)備通過(guò)ACK最后一個(gè)字節(jié)結(jié)束讀取序列,從而重置從設(shè)備的狀態(tài)機(jī)并允許主設(shè)備發(fā)送STOP條件。
備注:設(shè)備ID的讀取可以通過(guò)發(fā)送一個(gè)ACK在任何時(shí)候停止。
如果主設(shè)備繼續(xù)ACK第三個(gè)字節(jié)后的字節(jié),從設(shè)備回滾到第一個(gè)字節(jié)并繼續(xù)發(fā)送設(shè)備ID序列,直到檢測(cè)到一個(gè)ACK。
04
I2C傳輸數(shù)據(jù)的格式
4.1 寫操作
流程如下:
主芯片要發(fā)出一個(gè)start信號(hào)
然后發(fā)出一個(gè)設(shè)備地址(用來(lái)確定是往哪一個(gè)芯片寫數(shù)據(jù)),方向(讀/寫,0表示寫,1表示讀)
從設(shè)備回應(yīng)(用來(lái)確定這個(gè)設(shè)備是否存在),然后就可以傳輸數(shù)據(jù)
主設(shè)備發(fā)送一個(gè)字節(jié)數(shù)據(jù)給從設(shè)備,并等待回應(yīng)
每傳輸一字節(jié)數(shù)據(jù),接收方要有一個(gè)回應(yīng)信號(hào)(確定數(shù)據(jù)是否接受完成),然后再傳輸下一個(gè)數(shù)據(jù)。
數(shù)據(jù)發(fā)送完之后,主芯片就會(huì)發(fā)送一個(gè)停止信號(hào)。
下圖:白色背景表示"主→從",灰色背景表示"從→主"
4.2 讀操作
流程如下:
主芯片要發(fā)出一個(gè)start信號(hào)
然后發(fā)出一個(gè)設(shè)備地址(用來(lái)確定是往哪一個(gè)芯片寫數(shù)據(jù)),方向(讀/寫,0表示寫,1表示讀)
從設(shè)備回應(yīng)(用來(lái)確定這個(gè)設(shè)備是否存在),然后就可以傳輸數(shù)據(jù)
從設(shè)備發(fā)送一個(gè)字節(jié)數(shù)據(jù)給主設(shè)備,并等待回應(yīng)
每傳輸一字節(jié)數(shù)據(jù),接收方要有一個(gè)回應(yīng)信號(hào)(確定數(shù)據(jù)是否接受完成),然后再傳輸下一個(gè)數(shù)據(jù)。
數(shù)據(jù)發(fā)送完之后,主芯片就會(huì)發(fā)送一個(gè)停止信號(hào)。
下圖:白色背景表示"主→從",灰色背景表示"從→主"
4.3 I2C信號(hào)
I2C協(xié)議中數(shù)據(jù)傳輸?shù)膯挝皇亲止?jié),也就是8位。但是要用到9個(gè)時(shí)鐘:前面8個(gè)時(shí)鐘用來(lái)傳輸8數(shù)據(jù),第9個(gè)時(shí)鐘用來(lái)傳輸回應(yīng)信號(hào)。傳輸時(shí),先傳輸最高位(MSB)。
開(kāi)始信號(hào)(S):SCL為高電平時(shí),SDA山高電平向低電平跳變,開(kāi)始傳送數(shù)據(jù)。
結(jié)束信號(hào)(P):SCL為高電平時(shí),SDA由低電平向高電平跳變,結(jié)束傳送數(shù)據(jù)。
響應(yīng)信號(hào)(ACK):接收器在接收到8位數(shù)據(jù)后,在第9個(gè)時(shí)鐘周期,拉低SDA
SDA上傳輸?shù)臄?shù)據(jù)必須在SCL為高電平期間保持穩(wěn)定,SDA上的數(shù)據(jù)只能在SCL為低電平期間變化
I2C協(xié)議信號(hào)如下:
4.4 協(xié)議細(xì)節(jié)
如何在SDA上實(shí)現(xiàn)雙向傳輸?
主芯片通過(guò)一根SDA線既可以把數(shù)據(jù)發(fā)給從設(shè)備,也可以從SDA上讀取數(shù)據(jù),連接SDA線的引腳里面必然有兩個(gè)引腳(發(fā)送引腳/接受引腳)。
主、從設(shè)備都可以通過(guò)SDA發(fā)送數(shù)據(jù),肯定不能同時(shí)發(fā)送數(shù)據(jù),怎么錯(cuò)開(kāi)時(shí)間?
在9個(gè)時(shí)鐘里,
前8個(gè)時(shí)鐘由主設(shè)備發(fā)送數(shù)據(jù)的話,第9個(gè)時(shí)鐘就由從設(shè)備發(fā)送數(shù)據(jù);
前8個(gè)時(shí)鐘由從設(shè)備發(fā)送數(shù)據(jù)的話,第9個(gè)時(shí)鐘就由主設(shè)備發(fā)送數(shù)據(jù)。
雙方設(shè)備中,某個(gè)設(shè)備發(fā)送數(shù)據(jù)時(shí),另一方怎樣才能不影響SDA上的數(shù)據(jù)?
設(shè)備的SDA中有一個(gè)三極管,使用開(kāi)極/開(kāi)漏電路(三極管是開(kāi)極,CMOS管是開(kāi)漏,作用一樣),如下圖:
真值表如下:
從真值表和電路圖我們可以知道:
當(dāng)某一個(gè)芯片不想影響SDA線時(shí),那就不驅(qū)動(dòng)這個(gè)三極管
想讓SDA輸出高電平,雙方都不驅(qū)動(dòng)三極管(SDA通過(guò)上拉電阻變?yōu)楦唠娖?
想讓SDA輸出低電平,就驅(qū)動(dòng)三極管
4.5 示例:主設(shè)備發(fā)送(8bit)給從設(shè)備
從下面的例子可以看看數(shù)據(jù)是怎么傳的(實(shí)現(xiàn)雙向傳輸)。
舉例:主設(shè)備發(fā)送(8bit)給從設(shè)備
前8個(gè)clk
從設(shè)備不要影響SDA,從設(shè)備不驅(qū)動(dòng)三極管
主設(shè)備決定數(shù)據(jù),主設(shè)備要發(fā)送1時(shí)不驅(qū)動(dòng)三極管,要發(fā)送0時(shí)驅(qū)動(dòng)三極管
第9個(gè)clk,由從設(shè)備決定數(shù)據(jù)
主設(shè)備不驅(qū)動(dòng)三極管
從設(shè)備決定數(shù)據(jù),要發(fā)出回應(yīng)信號(hào)的話,就驅(qū)動(dòng)三極管讓SDA變?yōu)?
從這里也可以知道ACK信號(hào)是低電平
從上面的例子,就可以知道怎樣在一條線上實(shí)現(xiàn)雙向傳輸,這就是SDA上要使用上拉電阻的原因。
4.6 為何SCL也要使用上拉電阻?
在第9個(gè)時(shí)鐘之后,如果有某一方需要更多的時(shí)間來(lái)處理數(shù)據(jù),它可以一直驅(qū)動(dòng)三極管把SCL拉低。
當(dāng)SCL為低電平時(shí)候,大家都不應(yīng)該使用IIC總線,只有當(dāng)SCL從低電平變?yōu)楦唠娖降臅r(shí)候,IIC總線才能被使用。
當(dāng)它就緒后,就可以不再驅(qū)動(dòng)三極管,這是上拉電阻把SCL變?yōu)楦唠娖?,其他設(shè)備就可以繼續(xù)使用I2C總線了。
對(duì)于IIC協(xié)議它只能規(guī)定怎么傳輸數(shù)據(jù),數(shù)據(jù)是什么含義由從設(shè)備決定。
05
I2C通信的高級(jí)應(yīng)用
在嵌入式系統(tǒng)設(shè)計(jì)中,I2C應(yīng)用廣泛,如:
5.1 傳感器網(wǎng)絡(luò)
在多傳感器系統(tǒng)中,I2C用于讀取各種環(huán)境參數(shù),如溫度、濕度、光照強(qiáng)度等。這些數(shù)據(jù)可以被用于自動(dòng)化控制系統(tǒng)或數(shù)據(jù)監(jiān)測(cè)。
5.2 多設(shè)備控制
在復(fù)雜的嵌入式系統(tǒng)中,如機(jī)器人或無(wú)人機(jī),I2C用于控制和監(jiān)測(cè)多個(gè)執(zhí)行器和傳感器,實(shí)現(xiàn)精確的運(yùn)動(dòng)控制和環(huán)境反饋。
5.3 嵌入式通信網(wǎng)絡(luò)
I2C也常用于建立微控制器和各種外圍設(shè)備(如顯示屏、存儲(chǔ)設(shè)備等)之間的通信網(wǎng)絡(luò)。
本文章源自奇跡物聯(lián)開(kāi)源的物聯(lián)網(wǎng)應(yīng)用知識(shí)庫(kù)Cellular IoT Wiki,更多技術(shù)干貨歡迎關(guān)注收藏Wiki:Cellular IoT Wiki 知識(shí)庫(kù)(https://rckrv97mzx.feishu.cn/wiki/wikcnBvAC9WOkEYG5CLqGwm6PHf)
歡迎同學(xué)們走進(jìn)AmazIOT知識(shí)庫(kù)的世界!
這里是為物聯(lián)網(wǎng)人構(gòu)建的技術(shù)應(yīng)用百科,以便幫助你更快更簡(jiǎn)單的開(kāi)發(fā)物聯(lián)網(wǎng)產(chǎn)品。
Cellular IoT Wiki初心:
在我們長(zhǎng)期投身于蜂窩物聯(lián)網(wǎng) ODM/OEM 解決方案的實(shí)踐過(guò)程中,一直被物聯(lián)網(wǎng)技術(shù)碎片化與產(chǎn)業(yè)資源碎片化的問(wèn)題所困擾。從產(chǎn)品定義、芯片選型,到軟硬件研發(fā)和測(cè)試,物聯(lián)網(wǎng)技術(shù)的碎片化以及產(chǎn)業(yè)資源的碎片化,始終對(duì)團(tuán)隊(duì)的產(chǎn)品開(kāi)發(fā)交付質(zhì)量和效率形成制約。為了減少因物聯(lián)網(wǎng)碎片化而帶來(lái)的重復(fù)開(kāi)發(fā)工作,我們著手對(duì)物聯(lián)網(wǎng)開(kāi)發(fā)中高頻應(yīng)用的技術(shù)知識(shí)進(jìn)行沉淀管理,并基于 Bloom OS 搭建了不同平臺(tái)的 RTOS 應(yīng)用生態(tài)。后來(lái)我們發(fā)現(xiàn),很多物聯(lián)網(wǎng)產(chǎn)品開(kāi)發(fā)團(tuán)隊(duì)都面臨著相似的困擾,于是,我們決定向全體物聯(lián)網(wǎng)行業(yè)開(kāi)發(fā)者開(kāi)放奇跡物聯(lián)內(nèi)部沉淀的應(yīng)用技術(shù)知識(shí)庫(kù) Wiki,期望能為更多物聯(lián)網(wǎng)產(chǎn)品開(kāi)發(fā)者減輕一些重復(fù)造輪子的負(fù)擔(dān)。
Cellular IoT Wiki沉淀的技術(shù)內(nèi)容方向如下:
奇跡物聯(lián)的業(yè)務(wù)服務(wù)范圍:基于自研的NB-IoT、Cat1、Cat4等物聯(lián)網(wǎng)模組,為客戶物聯(lián)網(wǎng)ODM/OEM解決方案服務(wù)。我們的研發(fā)技術(shù)中心在石家莊,PCBA生產(chǎn)基地分布在深圳、石家莊、北京三個(gè)工廠,滿足不同區(qū)域&不同量產(chǎn)規(guī)模&不同產(chǎn)品開(kāi)發(fā)階段的生產(chǎn)制造任務(wù)。跟傳統(tǒng)PCBA工廠最大的區(qū)別是我們只服務(wù)物聯(lián)網(wǎng)行業(yè)客戶。
連接我們,和10000+物聯(lián)網(wǎng)開(kāi)發(fā)者一起降低技術(shù)和成本門檻
讓蜂窩物聯(lián)網(wǎng)應(yīng)用更簡(jiǎn)單~~
哈哈你終于滑到最重要的模塊了,
千萬(wàn)不!要!劃!走!忍住沖動(dòng)!~
歡迎加入飛書“開(kāi)源技術(shù)交流群”,隨時(shí)找到我們哦~
點(diǎn)擊鏈接如何加入奇跡物聯(lián)技術(shù)話題群(https://rckrv97mzx.feishu.cn/docx/Xskpd1cFQo7hu9x5EuicbsjTnTf)可以獲取加入技術(shù)話題群攻略
Hey 物聯(lián)網(wǎng)從業(yè)者,
你是否有了解過(guò)奇跡物聯(lián)的官方公眾號(hào)“eSIM物聯(lián)工場(chǎng)”呢?
這里是奇跡物聯(lián)的物聯(lián)網(wǎng)應(yīng)用技術(shù)開(kāi)源wiki主陣地,歡迎關(guān)注公眾號(hào),不迷路~
及時(shí)獲得最新物聯(lián)網(wǎng)應(yīng)用技術(shù)沉淀發(fā)布
審核編輯 黃宇
-
物聯(lián)網(wǎng)
+關(guān)注
關(guān)注
2909文章
44634瀏覽量
373316 -
總線
+關(guān)注
關(guān)注
10文章
2881瀏覽量
88081 -
I2C
+關(guān)注
關(guān)注
28文章
1487瀏覽量
123740 -
通信總線
+關(guān)注
關(guān)注
0文章
44瀏覽量
9854
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論