I2C -1-----I2C協(xié)議和工作流程
1.I2C的線控和收發(fā)步驟
I2C 總線是一個標準的雙向接口,使用一個稱為主器件的控制器與從器件進行通信。物理I2C接口由串行時鐘線SCL和串行數(shù)據(jù)線SDA組成。SDA和SCL線都必須通過上拉電阻器連接到VCC。上拉電阻器的大小由I2C線路上的電容量決定(有關(guān)I2C的Cbus計算后面會專門講到)。數(shù)據(jù)傳輸只能在總線空閑時啟動。如果在STOP條件后SDA和SCL線均為高電平,則總線被視為空閑。
除非被主器件成功尋址,否則從器件無法傳輸數(shù)據(jù)。I2C總線上的每個器件都有一個特定的器件地址,用于區(qū)分同一個I2C總線上的其他器件。許多從屬設(shè)備在啟動時需要配置以設(shè)置設(shè)備的行為。這通常在主機訪問具有唯一寄存器地址的從機內(nèi)部寄存器映射時完成。一個設(shè)備可以有一個或多個寄存器,用于存儲、寫入或讀取數(shù)據(jù)。I2C與器件之間的通信由主器件發(fā)送一個 啟動條件而開始, 并由主器件發(fā)送一個停止條件而終止。在SCL為高電平時在SDA線上進行的從高到低轉(zhuǎn)換定義了啟動條件。當主器件通過產(chǎn)生一個啟動條件控制了總線時,除非停止條件釋放總線,否則所有其他主器件都無法控制總線。在SCL為高電平時在SDA線上進行的 從低到高轉(zhuǎn)換定義了停止條件。在啟動條件與停止條件之間,必須執(zhí)行數(shù)據(jù)通信。
主設(shè)備訪問從屬設(shè)備的一般程序如下:
下面是主器件要向從器件發(fā)送或?qū)懭霐?shù)據(jù)時的步驟:
步驟一,主發(fā)送器發(fā)送一個啟動條件并尋找從接收器的地址。
步驟二,主發(fā)送器向從接收器發(fā)送數(shù)據(jù)。
步驟三,主發(fā)送器利用一個停止條件終止傳輸。
下面是主器件要從從器件接收或讀取數(shù)據(jù)時的步驟:
步驟一,主接收器發(fā)送一個啟動條件并尋找從發(fā)送器的地址。
步驟二,主接收機將請求的寄存器發(fā)送到從發(fā)射機進行讀取
步驟三,主接收器從從發(fā)送器接收數(shù)據(jù)。
步驟四,主接收器利用一個停止條件終止傳輸。
2.啟動和停止條件
與該設(shè)備的I2C通信由主機發(fā)送START條件啟動,并由主機發(fā)送STOP條件終止。當SCL為高時,SDA線上的高到低轉(zhuǎn)換定義了START條件。當SCL為高時,SDA線上的低到高轉(zhuǎn)換定義STOP條件。圖2-1演示了Start和Stop的波形:

圖2-1:啟動和停止條件示例
3.重復啟動條件
重復啟動條件類似于啟動條件,用于替代背靠背的先停止后啟動條件。它看起來與START條件相同,但與START條件不同,因為它發(fā)生在STOP條件之前(當總線不空閑時)。當主設(shè)備希望啟動新的通信,但不希望在STOP條件下讓總線空閑時,這非常有用,這有可能導致主設(shè)備失去對另一主設(shè)備的總線控制(在多主設(shè)備環(huán)境中)。
4. 數(shù)據(jù)有效性和字節(jié)格式
在SCL的每個時鐘脈沖期間傳送一個數(shù)據(jù)位。SDA線上的一個字節(jié)由八位組成。字節(jié)可以是設(shè)備地址、寄存器地址,也可以是從設(shè)備寫入或讀取的數(shù)據(jù)。數(shù)據(jù)首先傳輸最高有效位(MSB),最高有效位MSB位于數(shù)據(jù)幀的開頭, 最低有效位LSB位于數(shù)據(jù)幀的末尾, 后面跟隨確認ACK或未確認NACK。任何數(shù)量的數(shù)據(jù)字節(jié)都可以在START和STOP條件之間從主設(shè)備傳輸?shù)綇脑O(shè)備。SDA線上的數(shù)據(jù)必須在時鐘周期的高相位期間保持穩(wěn)定,因為SCL為高時數(shù)據(jù)線中的變化被解釋為控制命令(START或STOP)。

圖2-2:單字節(jié)數(shù)據(jù)傳輸示例,此時SDA線穩(wěn)定,SCL線高
圖2-2展示了一個發(fā)送1、0、1、0、1、0、1、0的示例,以十六進制表示為AA,包含一個ACK。當SCL為高電平時,會將數(shù)據(jù)線中的變化視為控制指令,例如啟動和停止。數(shù)據(jù)的每個字節(jié),包括地址字節(jié),后面都跟隨一個來自接收器的ACK位。ACK位允許接收器向發(fā)送器告知它已成功收到字節(jié),可以發(fā)送另一個字節(jié)了。在接收器可以發(fā)送ACK之前,發(fā)送器必須釋放 SDA 線。要發(fā)送ACK位,接收器必須在ACK/NACK相關(guān)時鐘周期,即周期9的低相位期間拉低 SDA 線。當SDA線在ACK/NACK相關(guān)時鐘周期期間保持高電平時,將被視為NACK。必須考慮設(shè)置時間和保持時間。
5.確認(ACK)和不確認(NACK)
有幾個條件會導致生成NACK。
條件一,接收器正在執(zhí)行某個實時功能,且未準備好開始與主器件進行通信,因此無法接收或發(fā)送數(shù)據(jù)。
條件二,在傳輸期間,接收器收到了它無法理解的數(shù)據(jù)或指令。
條件三,在傳輸期間,接收器無法再接收更多的數(shù)據(jù)字節(jié)。
條件四,主接收器已讀取數(shù)據(jù),并通過NACK向從器件表明了這種情況。

圖2-3:NACK示例,SDA線在ACK/NACK相關(guān)時鐘周期期間保持高電平時,視為NACK
6.數(shù)據(jù)傳輸
數(shù)據(jù)必須發(fā)送到從設(shè)備或從從設(shè)備接收數(shù)據(jù),但實現(xiàn)這一點的方式是讀取或?qū)懭霃脑O(shè)備中的寄存器。寄存器是從存儲器中包含信息的位置,無論是配置信息還是要發(fā)送回主存儲器的一些采樣數(shù)據(jù)。主設(shè)備必須將信息寫入這些寄存器,以便指示從設(shè)備執(zhí)行任務。雖然I2C從設(shè)備中有寄存器是常見的,但請注意,并非所有從設(shè)備都有寄存器。有些設(shè)備很簡單,只包含一個寄存器,可以通過在從地址之后立即發(fā)送寄存器數(shù)據(jù)而不是尋址寄存器來直接寫入。單個寄存器設(shè)備的一個例子是8位I2C開關(guān),它通過I2C命令控制。由于它有1位來啟用或禁用信道,所以只需要1個寄存器,而主機只在從地址之后寫入寄存器數(shù)據(jù),跳過寄存器號。
1.在I2C總線上寫入從設(shè)備:
圖2-4顯示了一個向從器件寫入兩個字節(jié)時的位和條件模式。主器件在總線上生成一個啟動條件。主器件生成一個7位的從器件地址以及最后一個位,即讀取/寫入位。在本例中,此位是一個寫入位,被設(shè)置為0,表示為負W。假設(shè)總線上存在一個具有此地址的從器件,則此從器件 會生成ACK。隨后,主器件會發(fā)送8個連續(xù)寄存器位或曰字節(jié),從器件隨后會生成一個ACK以 確認收到這些位。接下來,主器件會發(fā)送第二組連續(xù)位,也就是第二個字節(jié),從器件會隨即再次確認,以告知主器件它已收到此字節(jié)。然后,主器件會生成停止條件以終止此事務。
要在I2C總線上寫入,主設(shè)備將在總線上發(fā)送一個啟動條件,其中從設(shè)備的地址以及設(shè)置為0的最后一位(R/W位)表示寫入。在從設(shè)備發(fā)送確認位后,主設(shè)備將發(fā)送它希望寫入的寄存器的寄存器地址。從設(shè)備將再次確認,讓主設(shè)備知道它已經(jīng)準備好了。此后,主設(shè)備將開始向從設(shè)備發(fā)送寄存器數(shù)據(jù),直到主設(shè)備發(fā)送了所需的所有數(shù)據(jù)(有時僅為一個字節(jié)),并且主設(shè)備將在STOP條件下終止傳輸?;疑@示主機控制SDA線,白色顯示從機控制SDA線。

圖2-4:顯示了將單個字節(jié)寫入從寄存器的示例
2.從I2C總線上的從設(shè)備讀取:
從從設(shè)備上讀取與寫入非常相似,但需要額外的步驟。為了從從設(shè)備讀取數(shù)據(jù),主設(shè)備必須首先指示從設(shè)備要讀取的寄存器。這是通過主機以與寫入類似的方式開始傳輸,發(fā)送R/W位等于0(表示寫入)的地址,然后是它希望從中讀取的寄存器地址來完成的。一旦從設(shè)備確認該寄存器地址,主設(shè)備將再次發(fā)送START條件,隨后是R/W位設(shè)置為1的從設(shè)備地址(表示讀取)。這一次,從設(shè)備將確認讀取請求,主設(shè)備釋放SDA總線,但將繼續(xù)向從設(shè)備提供時鐘。在數(shù)據(jù)的這一部分,主設(shè)備將成為主接收機,從設(shè)備將成為從發(fā)射機。
主設(shè)備將繼續(xù)發(fā)送時鐘脈沖,但將釋放SDA線路,以便從設(shè)備可以傳輸數(shù)據(jù)。在數(shù)據(jù)的每個字節(jié)結(jié)束時,主機將向從機發(fā)送ACK,讓從機知道它已經(jīng)準備好接收更多數(shù)據(jù)。一旦主設(shè)備接收到預期的字節(jié)數(shù),它將發(fā)送NACK,向從設(shè)備發(fā)出信號以停止通信并釋放總線。主機將使用STOP(停止)條件進行跟蹤。

圖2-5:顯示了從從寄存器讀取單個字節(jié)的示例
圖2-5是一個從從器件讀取兩個字節(jié)的位和條件模式。主器件在總線上生成一個啟動條件。主器件生成7位的從器件地址以及最后一個位, 即讀取/寫入位。在本例中,此位是一個讀取位,被設(shè)置為 1,表示為字母R。假設(shè)總線上存在一個 具有此地址的從器件,則此從器件 會生成一個ACK。隨后,從器件會發(fā)送8個連續(xù)寄存器位或一個字節(jié),主器件隨后會生成一個ACK以確認收到這些位。接下來,從器件會發(fā)送第二組連續(xù)位,也就是第二個字節(jié),但主器件將不確認,即NACK,告知從器件它已接收完這些數(shù)據(jù)。然后,主器件會生成停止條件以終止此進程。這兩種模式代表主器件與從器件之間進行的最基本讀取和寫入操作。
電子發(fā)燒友App


















評論