I2C -1-----I2C協(xié)議和工作流程
1.I2C的線控和收發(fā)步驟
I2C 總線是一個(gè)標(biāo)準(zhǔn)的雙向接口,使用一個(gè)稱為主器件的控制器與從器件進(jìn)行通信。物理I2C接口由串行時(shí)鐘線SCL和串行數(shù)據(jù)線SDA組成。SDA和SCL線都必須通過上拉電阻器連接到VCC。上拉電阻器的大小由I2C線路上的電容量決定(有關(guān)I2C的Cbus計(jì)算后面會(huì)專門講到)。數(shù)據(jù)傳輸只能在總線空閑時(shí)啟動(dòng)。如果在STOP條件后SDA和SCL線均為高電平,則總線被視為空閑。
除非被主器件成功尋址,否則從器件無法傳輸數(shù)據(jù)。I2C總線上的每個(gè)器件都有一個(gè)特定的器件地址,用于區(qū)分同一個(gè)I2C總線上的其他器件。許多從屬設(shè)備在啟動(dòng)時(shí)需要配置以設(shè)置設(shè)備的行為。這通常在主機(jī)訪問具有唯一寄存器地址的從機(jī)內(nèi)部寄存器映射時(shí)完成。一個(gè)設(shè)備可以有一個(gè)或多個(gè)寄存器,用于存儲(chǔ)、寫入或讀取數(shù)據(jù)。I2C與器件之間的通信由主器件發(fā)送一個(gè) 啟動(dòng)條件而開始, 并由主器件發(fā)送一個(gè)停止條件而終止。在SCL為高電平時(shí)在SDA線上進(jìn)行的從高到低轉(zhuǎn)換定義了啟動(dòng)條件。當(dāng)主器件通過產(chǎn)生一個(gè)啟動(dòng)條件控制了總線時(shí),除非停止條件釋放總線,否則所有其他主器件都無法控制總線。在SCL為高電平時(shí)在SDA線上進(jìn)行的 從低到高轉(zhuǎn)換定義了停止條件。在啟動(dòng)條件與停止條件之間,必須執(zhí)行數(shù)據(jù)通信。
主設(shè)備訪問從屬設(shè)備的一般程序如下:
下面是主器件要向從器件發(fā)送或?qū)懭霐?shù)據(jù)時(shí)的步驟:
步驟一,主發(fā)送器發(fā)送一個(gè)啟動(dòng)條件并尋找從接收器的地址。
步驟二,主發(fā)送器向從接收器發(fā)送數(shù)據(jù)。
步驟三,主發(fā)送器利用一個(gè)停止條件終止傳輸。
下面是主器件要從從器件接收或讀取數(shù)據(jù)時(shí)的步驟:
步驟一,主接收器發(fā)送一個(gè)啟動(dòng)條件并尋找從發(fā)送器的地址。
步驟二,主接收機(jī)將請(qǐng)求的寄存器發(fā)送到從發(fā)射機(jī)進(jìn)行讀取
步驟三,主接收器從從發(fā)送器接收數(shù)據(jù)。
步驟四,主接收器利用一個(gè)停止條件終止傳輸。
2.啟動(dòng)和停止條件
與該設(shè)備的I2C通信由主機(jī)發(fā)送START條件啟動(dòng),并由主機(jī)發(fā)送STOP條件終止。當(dāng)SCL為高時(shí),SDA線上的高到低轉(zhuǎn)換定義了START條件。當(dāng)SCL為高時(shí),SDA線上的低到高轉(zhuǎn)換定義STOP條件。圖2-1演示了Start和Stop的波形:
圖2-1:啟動(dòng)和停止條件示例
3.重復(fù)啟動(dòng)條件
重復(fù)啟動(dòng)條件類似于啟動(dòng)條件,用于替代背靠背的先停止后啟動(dòng)條件。它看起來與START條件相同,但與START條件不同,因?yàn)樗l(fā)生在STOP條件之前(當(dāng)總線不空閑時(shí))。當(dāng)主設(shè)備希望啟動(dòng)新的通信,但不希望在STOP條件下讓總線空閑時(shí),這非常有用,這有可能導(dǎo)致主設(shè)備失去對(duì)另一主設(shè)備的總線控制(在多主設(shè)備環(huán)境中)。
4. 數(shù)據(jù)有效性和字節(jié)格式
在SCL的每個(gè)時(shí)鐘脈沖期間傳送一個(gè)數(shù)據(jù)位。SDA線上的一個(gè)字節(jié)由八位組成。字節(jié)可以是設(shè)備地址、寄存器地址,也可以是從設(shè)備寫入或讀取的數(shù)據(jù)。數(shù)據(jù)首先傳輸最高有效位(MSB),最高有效位MSB位于數(shù)據(jù)幀的開頭, 最低有效位LSB位于數(shù)據(jù)幀的末尾, 后面跟隨確認(rèn)ACK或未確認(rèn)NACK。任何數(shù)量的數(shù)據(jù)字節(jié)都可以在START和STOP條件之間從主設(shè)備傳輸?shù)綇脑O(shè)備。SDA線上的數(shù)據(jù)必須在時(shí)鐘周期的高相位期間保持穩(wěn)定,因?yàn)镾CL為高時(shí)數(shù)據(jù)線中的變化被解釋為控制命令(START或STOP)。
圖2-2:單字節(jié)數(shù)據(jù)傳輸示例,此時(shí)SDA線穩(wěn)定,SCL線高
圖2-2展示了一個(gè)發(fā)送1、0、1、0、1、0、1、0的示例,以十六進(jìn)制表示為AA,包含一個(gè)ACK。當(dāng)SCL為高電平時(shí),會(huì)將數(shù)據(jù)線中的變化視為控制指令,例如啟動(dòng)和停止。數(shù)據(jù)的每個(gè)字節(jié),包括地址字節(jié),后面都跟隨一個(gè)來自接收器的ACK位。ACK位允許接收器向發(fā)送器告知它已成功收到字節(jié),可以發(fā)送另一個(gè)字節(jié)了。在接收器可以發(fā)送ACK之前,發(fā)送器必須釋放 SDA 線。要發(fā)送ACK位,接收器必須在ACK/NACK相關(guān)時(shí)鐘周期,即周期9的低相位期間拉低 SDA 線。當(dāng)SDA線在ACK/NACK相關(guān)時(shí)鐘周期期間保持高電平時(shí),將被視為NACK。必須考慮設(shè)置時(shí)間和保持時(shí)間。
5.確認(rèn)(ACK)和不確認(rèn)(NACK)
有幾個(gè)條件會(huì)導(dǎo)致生成NACK。
條件一,接收器正在執(zhí)行某個(gè)實(shí)時(shí)功能,且未準(zhǔn)備好開始與主器件進(jìn)行通信,因此無法接收或發(fā)送數(shù)據(jù)。
條件二,在傳輸期間,接收器收到了它無法理解的數(shù)據(jù)或指令。
條件三,在傳輸期間,接收器無法再接收更多的數(shù)據(jù)字節(jié)。
條件四,主接收器已讀取數(shù)據(jù),并通過NACK向從器件表明了這種情況。
圖2-3:NACK示例,SDA線在ACK/NACK相關(guān)時(shí)鐘周期期間保持高電平時(shí),視為NACK
6.數(shù)據(jù)傳輸
數(shù)據(jù)必須發(fā)送到從設(shè)備或從從設(shè)備接收數(shù)據(jù),但實(shí)現(xiàn)這一點(diǎn)的方式是讀取或?qū)懭霃脑O(shè)備中的寄存器。寄存器是從存儲(chǔ)器中包含信息的位置,無論是配置信息還是要發(fā)送回主存儲(chǔ)器的一些采樣數(shù)據(jù)。主設(shè)備必須將信息寫入這些寄存器,以便指示從設(shè)備執(zhí)行任務(wù)。雖然I2C從設(shè)備中有寄存器是常見的,但請(qǐng)注意,并非所有從設(shè)備都有寄存器。有些設(shè)備很簡單,只包含一個(gè)寄存器,可以通過在從地址之后立即發(fā)送寄存器數(shù)據(jù)而不是尋址寄存器來直接寫入。單個(gè)寄存器設(shè)備的一個(gè)例子是8位I2C開關(guān),它通過I2C命令控制。由于它有1位來啟用或禁用信道,所以只需要1個(gè)寄存器,而主機(jī)只在從地址之后寫入寄存器數(shù)據(jù),跳過寄存器號(hào)。
1.在I2C總線上寫入從設(shè)備:
圖2-4顯示了一個(gè)向從器件寫入兩個(gè)字節(jié)時(shí)的位和條件模式。主器件在總線上生成一個(gè)啟動(dòng)條件。主器件生成一個(gè)7位的從器件地址以及最后一個(gè)位,即讀取/寫入位。在本例中,此位是一個(gè)寫入位,被設(shè)置為0,表示為負(fù)W。假設(shè)總線上存在一個(gè)具有此地址的從器件,則此從器件 會(huì)生成ACK。隨后,主器件會(huì)發(fā)送8個(gè)連續(xù)寄存器位或曰字節(jié),從器件隨后會(huì)生成一個(gè)ACK以 確認(rèn)收到這些位。接下來,主器件會(huì)發(fā)送第二組連續(xù)位,也就是第二個(gè)字節(jié),從器件會(huì)隨即再次確認(rèn),以告知主器件它已收到此字節(jié)。然后,主器件會(huì)生成停止條件以終止此事務(wù)。
要在I2C總線上寫入,主設(shè)備將在總線上發(fā)送一個(gè)啟動(dòng)條件,其中從設(shè)備的地址以及設(shè)置為0的最后一位(R/W位)表示寫入。在從設(shè)備發(fā)送確認(rèn)位后,主設(shè)備將發(fā)送它希望寫入的寄存器的寄存器地址。從設(shè)備將再次確認(rèn),讓主設(shè)備知道它已經(jīng)準(zhǔn)備好了。此后,主設(shè)備將開始向從設(shè)備發(fā)送寄存器數(shù)據(jù),直到主設(shè)備發(fā)送了所需的所有數(shù)據(jù)(有時(shí)僅為一個(gè)字節(jié)),并且主設(shè)備將在STOP條件下終止傳輸?;疑@示主機(jī)控制SDA線,白色顯示從機(jī)控制SDA線。
圖2-4:顯示了將單個(gè)字節(jié)寫入從寄存器的示例
2.從I2C總線上的從設(shè)備讀取:
從從設(shè)備上讀取與寫入非常相似,但需要額外的步驟。為了從從設(shè)備讀取數(shù)據(jù),主設(shè)備必須首先指示從設(shè)備要讀取的寄存器。這是通過主機(jī)以與寫入類似的方式開始傳輸,發(fā)送R/W位等于0(表示寫入)的地址,然后是它希望從中讀取的寄存器地址來完成的。一旦從設(shè)備確認(rèn)該寄存器地址,主設(shè)備將再次發(fā)送START條件,隨后是R/W位設(shè)置為1的從設(shè)備地址(表示讀取)。這一次,從設(shè)備將確認(rèn)讀取請(qǐng)求,主設(shè)備釋放SDA總線,但將繼續(xù)向從設(shè)備提供時(shí)鐘。在數(shù)據(jù)的這一部分,主設(shè)備將成為主接收機(jī),從設(shè)備將成為從發(fā)射機(jī)。
主設(shè)備將繼續(xù)發(fā)送時(shí)鐘脈沖,但將釋放SDA線路,以便從設(shè)備可以傳輸數(shù)據(jù)。在數(shù)據(jù)的每個(gè)字節(jié)結(jié)束時(shí),主機(jī)將向從機(jī)發(fā)送ACK,讓從機(jī)知道它已經(jīng)準(zhǔn)備好接收更多數(shù)據(jù)。一旦主設(shè)備接收到預(yù)期的字節(jié)數(shù),它將發(fā)送NACK,向從設(shè)備發(fā)出信號(hào)以停止通信并釋放總線。主機(jī)將使用STOP(停止)條件進(jìn)行跟蹤。
圖2-5:顯示了從從寄存器讀取單個(gè)字節(jié)的示例
圖2-5是一個(gè)從從器件讀取兩個(gè)字節(jié)的位和條件模式。主器件在總線上生成一個(gè)啟動(dòng)條件。主器件生成7位的從器件地址以及最后一個(gè)位, 即讀取/寫入位。在本例中,此位是一個(gè)讀取位,被設(shè)置為 1,表示為字母R。假設(shè)總線上存在一個(gè) 具有此地址的從器件,則此從器件 會(huì)生成一個(gè)ACK。隨后,從器件會(huì)發(fā)送8個(gè)連續(xù)寄存器位或一個(gè)字節(jié),主器件隨后會(huì)生成一個(gè)ACK以確認(rèn)收到這些位。接下來,從器件會(huì)發(fā)送第二組連續(xù)位,也就是第二個(gè)字節(jié),但主器件將不確認(rèn),即NACK,告知從器件它已接收完這些數(shù)據(jù)。然后,主器件會(huì)生成停止條件以終止此進(jìn)程。這兩種模式代表主器件與從器件之間進(jìn)行的最基本讀取和寫入操作。
評(píng)論
查看更多