i2c時(shí)序圖的詳細(xì)講解


I2C 時(shí)序圖的深度解析
I2C(Inter-Integrated Circuit)總線,作為一種由飛利浦(現(xiàn)為恩智浦半導(dǎo)體)在20世紀(jì)80年代初開發(fā)的串行通信協(xié)議,因其簡(jiǎn)潔高效、僅需兩根線(SDA和SCL)即可實(shí)現(xiàn)主從設(shè)備間通信的特性,在全球范圍內(nèi)得到了廣泛應(yīng)用。從微控制器到傳感器、EEPROM、實(shí)時(shí)時(shí)鐘,乃至更復(fù)雜的嵌入式系統(tǒng),I2C幾乎無處不在。理解I2C時(shí)序圖是掌握其工作原理、進(jìn)行有效系統(tǒng)設(shè)計(jì)以及故障排除的關(guān)鍵。本章將對(duì)I2C時(shí)序圖進(jìn)行極其詳盡的解析,從基本概念到高級(jí)特性,力求涵蓋所有重要方面。
1. I2C 總線基礎(chǔ)概述與核心概念
在深入探討時(shí)序圖之前,我們必須對(duì)I2C總線的幾個(gè)核心概念有清晰的認(rèn)識(shí)。I2C是一種半雙工、多主從、同步串行總線。這意味著數(shù)據(jù)在同一時(shí)間只能在一個(gè)方向上傳輸(半雙工),總線上可以有多個(gè)主設(shè)備和多個(gè)從設(shè)備(多主從),并且通信是通過一個(gè)共享的時(shí)鐘信號(hào)進(jìn)行同步的(同步串行)。
1.1. 兩線接口:SDA與SCL
I2C總線僅依賴兩根信號(hào)線:
SDA (Serial Data Line):串行數(shù)據(jù)線。這是一條雙向線,用于傳輸數(shù)據(jù)。數(shù)據(jù)傳輸在SDA線上以比特為單位進(jìn)行,每個(gè)比特位都在SCL的一個(gè)時(shí)鐘周期內(nèi)有效。
SCL (Serial Clock Line):串行時(shí)鐘線。這是一條單向線(通常由主設(shè)備驅(qū)動(dòng),但在多主設(shè)備環(huán)境中可由從設(shè)備拉低以實(shí)現(xiàn)時(shí)鐘延長(zhǎng)),用于同步數(shù)據(jù)傳輸。所有連接到總線的設(shè)備都通過SCL信號(hào)的上升沿和下降沿來同步它們的內(nèi)部操作和數(shù)據(jù)采樣。
這兩條線都是開漏輸出(Open-Drain)。這意味著它們只能將信號(hào)線拉低到地(邏輯“0”),而不能主動(dòng)將其拉高。當(dāng)總線空閑時(shí),它們由外部的上拉電阻(Pull-up Resistor)拉高到電源電壓(邏輯“1”)。這種開漏結(jié)構(gòu)有幾個(gè)優(yōu)點(diǎn):
線與(Wired-AND)功能:多個(gè)設(shè)備可以連接到同一條總線,只要其中任何一個(gè)設(shè)備將總線拉低,總線就會(huì)呈現(xiàn)低電平。只有當(dāng)所有設(shè)備都釋放總線(即不再拉低)時(shí),總線才能被上拉電阻拉高。這對(duì)于多主設(shè)備仲裁和從設(shè)備時(shí)鐘延長(zhǎng)至關(guān)重要。
防止總線沖突損壞:如果兩個(gè)設(shè)備同時(shí)嘗試將總線驅(qū)動(dòng)到相反的狀態(tài)(一個(gè)驅(qū)動(dòng)高,一個(gè)驅(qū)動(dòng)低),開漏輸出可以防止大電流流過而損壞設(shè)備。
上拉電阻的選擇非常重要。過大的電阻會(huì)導(dǎo)致信號(hào)上升時(shí)間過長(zhǎng),影響通信速度;過小的電阻則會(huì)增加功耗,并可能限制可連接設(shè)備的數(shù)量。通常,上拉電阻的典型值在1kΩ到10kΩ之間,具體取決于總線電容和通信速率。
1.2. 主設(shè)備與從設(shè)備
主設(shè)備(Master):負(fù)責(zé)啟動(dòng)數(shù)據(jù)傳輸、生成時(shí)鐘信號(hào)(SCL)以及終止傳輸。一個(gè)I2C總線上可以有多個(gè)主設(shè)備。
從設(shè)備(Slave):響應(yīng)主設(shè)備的尋址,并根據(jù)主設(shè)備的要求發(fā)送或接收數(shù)據(jù)。從設(shè)備通常是傳感器、存儲(chǔ)器等外設(shè),它們不主動(dòng)發(fā)起通信,而是被動(dòng)地等待主設(shè)備的指令。
1.3. 尋址
I2C總線上每個(gè)從設(shè)備都有一個(gè)唯一的7位或10位地址。主設(shè)備通過廣播這個(gè)地址來選擇與哪個(gè)從設(shè)備進(jìn)行通信。只有地址匹配的從設(shè)備才會(huì)響應(yīng)。7位地址是最常見的,而10位地址則用于支持更多設(shè)備連接到同一總線。
1.4. 數(shù)據(jù)傳輸方向
I2C的數(shù)據(jù)傳輸方向是雙向的,但每個(gè)字節(jié)傳輸時(shí),主設(shè)備會(huì)發(fā)送一個(gè)方向位(讀/寫位),指示接下來的數(shù)據(jù)是由主設(shè)備寫入從設(shè)備(寫操作)還是由從設(shè)備發(fā)送給主設(shè)備(讀操作)。
1.5. 速率模式
I2C規(guī)范定義了多種通信速率模式,以適應(yīng)不同的應(yīng)用需求:
標(biāo)準(zhǔn)模式(Standard-mode):最高100 kbit/s。這是最常見的模式,適用于大多數(shù)通用應(yīng)用。
快速模式(Fast-mode):最高400 kbit/s。提供更高的數(shù)據(jù)吞吐量,適用于需要更快響應(yīng)的傳感器或存儲(chǔ)器。
快速模式+(Fast-mode Plus):最高1 Mbit/s。進(jìn)一步提升速度,通常需要更低的上拉電阻和更嚴(yán)格的PCB布線要求。
高速模式(High-speed mode, Hs-mode):最高3.4 Mbit/s。利用獨(dú)特的機(jī)制(如主設(shè)備SCL的低電平周期短路)實(shí)現(xiàn)更高速度,但需要兼容的設(shè)備。
超快速模式(Ultra Fast-mode):?jiǎn)蜗蛲ㄐ?,最? Mbit/s。主要用于顯示器控制等特定應(yīng)用。
這些速率模式在時(shí)序上存在差異,尤其是在SCL的頻率和SDA的數(shù)據(jù)建立/保持時(shí)間上。
2. I2C 基本時(shí)序:開始、停止、數(shù)據(jù)傳輸與應(yīng)答
I2C總線上的所有通信都圍繞著幾個(gè)基本且嚴(yán)格定義的時(shí)序事件展開。理解這些事件的時(shí)序圖是理解整個(gè)通信過程的關(guān)鍵。
2.1. 空閑狀態(tài)(Bus Idle State)
當(dāng)I2C總線處于空閑狀態(tài)時(shí),SDA和SCL兩條線都由上拉電阻拉高,保持在高電平(邏輯“1”)。這表明總線上沒有數(shù)據(jù)傳輸正在進(jìn)行。
(圖片來源:網(wǎng)絡(luò)示意圖,表示SDA和SCL高電平)
2.2. 開始條件(START Condition)
所有I2C通信都必須以一個(gè)開始條件作為開端。開始條件由主設(shè)備生成,其定義為:在SCL為高電平期間,SDA線從高電平跳變到低電平。
時(shí)序細(xì)節(jié):
主設(shè)備首先確保SCL和SDA都處于高電平。
在SCL保持高電平的情況下,主設(shè)備將SDA拉低。
SDA拉低后,主設(shè)備將SCL也拉低,準(zhǔn)備發(fā)送第一個(gè)數(shù)據(jù)位。
開始條件是主設(shè)備宣告“我要開始通信了”的方式。總線上的所有從設(shè)備都會(huì)監(jiān)聽開始條件,并在檢測(cè)到它之后進(jìn)入活動(dòng)狀態(tài),準(zhǔn)備接收尋址信息。
(圖片來源:ElectronicWings,表示SCL高電平,SDA由高到低)
2.3. 停止條件(STOP Condition)
當(dāng)一次通信結(jié)束時(shí),主設(shè)備會(huì)生成一個(gè)停止條件來釋放總線。停止條件定義為:在SCL為高電平期間,SDA線從低電平跳變到高電平。
時(shí)序細(xì)節(jié):
在發(fā)送完最后一個(gè)數(shù)據(jù)位或應(yīng)答位后,主設(shè)備首先將SCL拉低。
然后,主設(shè)備確保SDA處于低電平。
在SCL保持高電平的情況下,主設(shè)備將SDA從低電平拉高。
SDA拉高后,SCL也保持高電平,總線恢復(fù)到空閑狀態(tài)。
停止條件標(biāo)志著當(dāng)前通信的結(jié)束,并允許其他主設(shè)備有機(jī)會(huì)使用總線。
(圖片來源:ElectronicWings,表示SCL高電平,SDA由低到高)
2.4. 數(shù)據(jù)傳輸(Data Transfer)
在開始條件之后,數(shù)據(jù)(包括地址、讀/寫方向位和實(shí)際數(shù)據(jù)字節(jié))以8位字節(jié)的形式在SDA線上串行傳輸。每個(gè)字節(jié)傳輸完成后,會(huì)跟隨一個(gè)應(yīng)答位。
時(shí)序細(xì)節(jié):
時(shí)鐘同步:SDA上的數(shù)據(jù)在SCL的每個(gè)高電平期間保持穩(wěn)定。主設(shè)備在SCL的下降沿之后改變SDA上的數(shù)據(jù),并在SCL的上升沿采樣SDA上的數(shù)據(jù)。從設(shè)備也在SCL的上升沿采樣數(shù)據(jù)。
比特順序:每個(gè)字節(jié)的數(shù)據(jù)都是最高有效位(MSB)優(yōu)先傳輸。這意味著字節(jié)的第7位(D7)首先被發(fā)送,然后是D6,以此類推,直到D0。
數(shù)據(jù)有效性:在SCL為高電平期間,SDA線上的數(shù)據(jù)必須保持穩(wěn)定。SDA上的任何變化都只能發(fā)生在SCL為低電平期間。這是區(qū)分?jǐn)?shù)據(jù)位和開始/停止條件的關(guān)鍵。
一個(gè)完整的字節(jié)傳輸需要8個(gè)SCL時(shí)鐘周期。
(圖片來源:ElectronicWings,表示SCL高電平期間SDA穩(wěn)定,SCL低電平期間SDA可變)
2.5. 應(yīng)答(ACK)與非應(yīng)答(NACK)
在每個(gè)字節(jié)(包括地址字節(jié))傳輸完成后,接收方(無論是主設(shè)備還是從設(shè)備)都必須生成一個(gè)應(yīng)答位(ACK)或非應(yīng)答位(NACK),以告知發(fā)送方數(shù)據(jù)是否已成功接收。
應(yīng)答(ACK - Acknowledge):
接收方在發(fā)送方釋放SDA線后,在第9個(gè)SCL時(shí)鐘周期(應(yīng)答時(shí)鐘周期)將SDA線拉低。
這表示接收方已成功接收并準(zhǔn)備好接收下一個(gè)字節(jié)。
主設(shè)備發(fā)送數(shù)據(jù)給從設(shè)備時(shí),從設(shè)備產(chǎn)生ACK。
從設(shè)備發(fā)送數(shù)據(jù)給主設(shè)備時(shí),主設(shè)備產(chǎn)生ACK。
非應(yīng)答(NACK - Not Acknowledge):
接收方在發(fā)送方釋放SDA線后,在第9個(gè)SCL時(shí)鐘周期將SDA線保持在高電平(不拉低)。
這表示接收方未能接收數(shù)據(jù)(例如,設(shè)備不存在、忙碌或數(shù)據(jù)格式錯(cuò)誤),或者發(fā)送方希望結(jié)束數(shù)據(jù)傳輸。
在主設(shè)備從從設(shè)備讀取數(shù)據(jù)的場(chǎng)景中,主設(shè)備通常在讀取最后一個(gè)字節(jié)后發(fā)送NACK,以告知從設(shè)備它不再需要更多數(shù)據(jù),并準(zhǔn)備生成停止條件。
應(yīng)答位是I2C協(xié)議健壯性的一個(gè)重要組成部分,它提供了錯(cuò)誤檢測(cè)和流量控制的基本機(jī)制。
(圖片來源:ElectronicWings,表示第9個(gè)時(shí)鐘周期SDA的狀態(tài))
3. I2C 通信流程與時(shí)序圖詳解
理解了基本時(shí)序事件后,我們現(xiàn)在可以將它們組合起來,分析典型的I2C通信流程,并深入探討其時(shí)序圖。
3.1. I2C 寫操作時(shí)序(Master Transmits to Slave)
在寫操作中,主設(shè)備向從設(shè)備發(fā)送數(shù)據(jù)。典型的I2C寫操作流程如下:
開始條件(START Condition):主設(shè)備生成開始條件,SCL高電平期間SDA由高到低。
發(fā)送7位從設(shè)備地址 + 寫方向位:
主設(shè)備接著發(fā)送7位從設(shè)備地址。這是主設(shè)備要與之通信的特定從設(shè)備的唯一地址。
在7位地址之后,主設(shè)備發(fā)送第8位:讀/寫方向位(R/W#)。對(duì)于寫操作,此位為0(邏輯低)。
這8位數(shù)據(jù)(地址+R/W#)在8個(gè)SCL時(shí)鐘周期內(nèi)傳輸,MSB在前。
從設(shè)備應(yīng)答(ACK):被尋址的從設(shè)備在第9個(gè)SCL時(shí)鐘周期將SDA拉低,表示已接收到地址并準(zhǔn)備好接收數(shù)據(jù)。如果沒有從設(shè)備應(yīng)答,主設(shè)備將認(rèn)為通信失敗,并通常會(huì)生成停止條件。
發(fā)送數(shù)據(jù)字節(jié):主設(shè)備接著發(fā)送一個(gè)或多個(gè)數(shù)據(jù)字節(jié)。每個(gè)數(shù)據(jù)字節(jié)都是8位,MSB在前。
從設(shè)備應(yīng)答:每發(fā)送完一個(gè)數(shù)據(jù)字節(jié),從設(shè)備都必須在第9個(gè)SCL時(shí)鐘周期生成一個(gè)ACK,以確認(rèn)收到數(shù)據(jù)。
重復(fù)步驟4和5,直到所有數(shù)據(jù)發(fā)送完畢。
停止條件(STOP Condition):主設(shè)備在發(fā)送完最后一個(gè)數(shù)據(jù)字節(jié)并收到從設(shè)備的ACK后,生成停止條件,SCL高電平期間SDA由低到高,釋放總線。
時(shí)序圖概覽(寫操作):
SCL __| |_____| | | | | | |_____| | | | | |_____| |
| | | | | | | | | | | | | | | |
SDA ----|---|-----+-+-+-+-+-+-+-+-+-+-+-----+-+-+-+-+-+-+-+-+-+-+-----+-+-+-----
| S | A7|A6|A5|A4|A3|A2|A1|R/W| ACK | D7|D6|D5|D4|D3|D2|D1|D0| ACK | P |
| T |----------------- Address ----------------| Data Byte |
| A | | |
| R | | |
| T | | |
SCL:時(shí)鐘信號(hào),由主設(shè)備生成。
SDA:數(shù)據(jù)信號(hào)。
S:開始條件。
A7-A1:7位從設(shè)備地址。
R/W#:讀/寫方向位,0表示寫。
ACK:應(yīng)答位,從設(shè)備拉低SDA。
D7-D0:8位數(shù)據(jù)字節(jié)。
P:停止條件。
在SCL的每個(gè)高電平周期,SDA線上的數(shù)據(jù)(包括地址位、R/W#位和數(shù)據(jù)位)都必須是穩(wěn)定的。SDA的任何變化都只發(fā)生在SCL的低電平周期。
3.2. I2C 讀操作時(shí)序(Master Receives from Slave)
在讀操作中,主設(shè)備從從設(shè)備接收數(shù)據(jù)。I2C的讀操作通常分為兩個(gè)階段:尋址和讀取。
開始條件(START Condition):主設(shè)備生成開始條件。
發(fā)送7位從設(shè)備地址 + 寫方向位:
主設(shè)備發(fā)送7位從設(shè)備地址,但R/W#位仍為0(寫操作)。
重要:這看起來像寫操作,但其目的是為了告訴從設(shè)備主設(shè)備正在嘗試與之通信,并可能需要設(shè)置一些內(nèi)部寄存器(例如,指向要讀取的數(shù)據(jù)地址)。有些從設(shè)備在讀操作前不需要額外的數(shù)據(jù)寫入,但大多數(shù)都需要。
從設(shè)備應(yīng)答(ACK):被尋址的從設(shè)備應(yīng)答。
(可選)發(fā)送寄存器地址/內(nèi)部地址:如果從設(shè)備內(nèi)部有多個(gè)寄存器需要訪問,主設(shè)備會(huì)發(fā)送一個(gè)或多個(gè)字節(jié)來指定要讀取的寄存器地址。這部分屬于寫操作的范疇。
從設(shè)備應(yīng)答(ACK)。
重復(fù)開始條件(Repeated START Condition):
這是讀操作的關(guān)鍵一步。主設(shè)備在不生成停止條件的情況下,再次生成一個(gè)開始條件。
這表示主設(shè)備將繼續(xù)與同一個(gè)從設(shè)備通信,但現(xiàn)在要改變通信方向。
發(fā)送7位從設(shè)備地址 + 讀方向位:
主設(shè)備再次發(fā)送相同的7位從設(shè)備地址。
但這次,R/W#位為1(邏輯高),表示主設(shè)備現(xiàn)在要從從設(shè)備讀取數(shù)據(jù)。
從設(shè)備應(yīng)答(ACK):從設(shè)備應(yīng)答,表示它已準(zhǔn)備好發(fā)送數(shù)據(jù)。
接收數(shù)據(jù)字節(jié):從設(shè)備開始向主設(shè)備發(fā)送數(shù)據(jù)字節(jié)。每個(gè)字節(jié)是8位,MSB在前。
主設(shè)備應(yīng)答(ACK):每接收完一個(gè)數(shù)據(jù)字節(jié),主設(shè)備必須在第9個(gè)SCL時(shí)鐘周期生成一個(gè)ACK,以確認(rèn)收到數(shù)據(jù),并指示從設(shè)備發(fā)送下一個(gè)字節(jié)。
主設(shè)備非應(yīng)答(NACK):當(dāng)主設(shè)備收到最后一個(gè)所需的數(shù)據(jù)字節(jié)后,它在第9個(gè)SCL時(shí)鐘周期生成一個(gè)NACK(將SDA保持高電平),告知從設(shè)備它不需要更多數(shù)據(jù)。這是告訴從設(shè)備停止傳輸數(shù)據(jù)的信號(hào)。
停止條件(STOP Condition):主設(shè)備在發(fā)送NACK后,生成停止條件,釋放總線。
時(shí)序圖概覽(讀操作):
SCL __| |_____| | | | | | |_____| | |_____| | |_____| | | | | | |_____| | |_____| |
| | | | | | | | | | | | | | | | | | | | | | | | | |
SDA ----|---|-----+-+-+-+-+-+-+-+-+-+-+-----+-+-+-+-----|---|-----+-+-+-+-+-+-+-+-+-+-+-----+-+-+-+-----+-+-+-----
| S | A7|...|A1|R/W=0| ACK | R | DATA | ACK | R | S | A7|...|A1|R/W=1| ACK | D7|...|D0| ACK | D7|...|D0| NACK| P |
| T |----------------- Address ----------------| | (Reg Addr)| | T |----------------- Address ----------------| Data Byte 1 | Data Byte 2 |
| A | | E | | | A | | | |
| R | | P | | | R | | | |
| T | | E | | | T | | | |
S:開始條件。
S:開始條件。
R:可選的寄存器地址寫入。
REPEATED S:重復(fù)開始條件。
R/W=0:第一次地址傳輸,方向位為寫。
R/W=1:第二次地址傳輸,方向位為讀。
D7-D0:從設(shè)備發(fā)送的數(shù)據(jù)字節(jié)。
ACK(Master):主設(shè)備應(yīng)答,表示繼續(xù)接收。
NACK(Master):主設(shè)備非應(yīng)答,表示不再接收,準(zhǔn)備停止。
P:停止條件。
重復(fù)開始條件(Repeated START)非常重要,它允許主設(shè)備在不釋放總線控制權(quán)的情況下改變通信方向,或者在不結(jié)束當(dāng)前事務(wù)的情況下與另一個(gè)從設(shè)備通信。這對(duì)于需要原子操作的場(chǎng)景(例如,在不讓其他主設(shè)備有機(jī)會(huì)插入的情況下先寫一個(gè)寄存器再讀取其內(nèi)容)非常有用。
3.3. I2C 10位地址尋址時(shí)序
雖然7位地址是主流,但I(xiàn)2C規(guī)范也支持10位地址。10位地址尋址涉及兩個(gè)字節(jié)的地址傳輸,并且其尋址字節(jié)有特殊的格式。
10位地址寫操作時(shí)序:
開始條件(START Condition)。
發(fā)送第一個(gè)地址字節(jié):
格式:
1111 0XX0
(MSB在前)11110
:這是10位地址的固定前綴。XX
:這是10位地址的最高2位(A9和A8)。0
:這是R/W#位,表示寫操作。從設(shè)備應(yīng)答(ACK):被尋址的從設(shè)備應(yīng)答。
發(fā)送第二個(gè)地址字節(jié):
格式:
A7 A6 A5 A4 A3 A2 A1 A0
這是10位地址的最低8位。
從設(shè)備應(yīng)答(ACK):從設(shè)備應(yīng)答。
發(fā)送數(shù)據(jù)字節(jié):主設(shè)備發(fā)送數(shù)據(jù)字節(jié),每個(gè)字節(jié)后從設(shè)備應(yīng)答。
停止條件(STOP Condition)。
10位地址讀操作時(shí)序:
開始條件(START Condition)。
發(fā)送第一個(gè)地址字節(jié):
格式:
1111 0XX0
(R/W#=0,寫)從設(shè)備應(yīng)答(ACK)。
發(fā)送第二個(gè)地址字節(jié):
格式:
A7 A6 A5 A4 A3 A2 A1 A0
從設(shè)備應(yīng)答(ACK)。
重復(fù)開始條件(Repeated START Condition)。
發(fā)送第一個(gè)地址字節(jié)(再次):
格式:
1111 0XX1
(R/W#=1,讀)從設(shè)備應(yīng)答(ACK)。
從設(shè)備發(fā)送數(shù)據(jù)字節(jié):從設(shè)備開始發(fā)送數(shù)據(jù)。
主設(shè)備應(yīng)答(ACK),直到收到最后一個(gè)字節(jié)。
主設(shè)備非應(yīng)答(NACK)。
停止條件(STOP Condition)。
10位地址的復(fù)雜性在于,它的前兩個(gè)字節(jié)都用于尋址,并且第一個(gè)字節(jié)的固定前綴確保了與7位地址設(shè)備的兼容性。
4. I2C 高級(jí)時(shí)序與特性
除了基本的讀寫操作,I2C協(xié)議還包含一些高級(jí)特性,它們?cè)谔囟ǖ膽?yīng)用場(chǎng)景中提供了更大的靈活性和魯棒性。
4.1. 時(shí)鐘延長(zhǎng)(Clock Stretching / Clock Synchronization)
時(shí)鐘延長(zhǎng)是I2C協(xié)議中一個(gè)非常重要的特性,它允許從設(shè)備在處理數(shù)據(jù)或準(zhǔn)備響應(yīng)時(shí)暫時(shí)暫停通信。當(dāng)從設(shè)備需要更多時(shí)間時(shí),它可以將SCL線拉低,阻止主設(shè)備釋放SCL線,從而延長(zhǎng)當(dāng)前時(shí)鐘周期的低電平時(shí)間。
時(shí)序細(xì)節(jié):
在主設(shè)備將SCL拉低后(通常是在發(fā)送完一個(gè)數(shù)據(jù)位或應(yīng)答位之后),從設(shè)備可以在SCL應(yīng)該由高電平變?yōu)榈碗娖降臅r(shí)候,將SCL線繼續(xù)保持在低電平。
主設(shè)備會(huì)檢測(cè)到SCL線仍然是低電平,即使它已經(jīng)釋放了SCL線(通過內(nèi)部上拉,或者等待外部上拉電阻將其拉高),它也會(huì)等待SCL線被拉高。
當(dāng)從設(shè)備完成內(nèi)部操作并準(zhǔn)備好繼續(xù)通信時(shí),它會(huì)釋放SCL線。此時(shí),SCL線由上拉電阻拉高,主設(shè)備檢測(cè)到SCL高電平,然后繼續(xù)其時(shí)鐘生成。
應(yīng)用場(chǎng)景:
數(shù)據(jù)準(zhǔn)備:從設(shè)備可能需要時(shí)間來讀取傳感器數(shù)據(jù)、執(zhí)行內(nèi)部計(jì)算或從存儲(chǔ)器中檢索數(shù)據(jù)。
忙碌狀態(tài):從設(shè)備可能在執(zhí)行其他任務(wù),無法立即響應(yīng)主設(shè)備的請(qǐng)求。
時(shí)鐘延長(zhǎng)確保了從設(shè)備有足夠的時(shí)間來處理數(shù)據(jù),避免了數(shù)據(jù)丟失或通信錯(cuò)誤。然而,過度或不恰當(dāng)?shù)臅r(shí)鐘延長(zhǎng)會(huì)顯著降低總線吞吐量,甚至可能導(dǎo)致主設(shè)備超時(shí)。主設(shè)備驅(qū)動(dòng)程序通常需要實(shí)現(xiàn)超時(shí)機(jī)制,以防止從設(shè)備無限期地延長(zhǎng)時(shí)鐘。
(圖片來源:SparkFun,表示SCL低電平被從設(shè)備延長(zhǎng))
4.2. 總線仲裁(Bus Arbitration)
在多主設(shè)備I2C系統(tǒng)中,當(dāng)多個(gè)主設(shè)備同時(shí)嘗試啟動(dòng)通信時(shí),總線仲裁機(jī)制可以解決沖突,確保只有一個(gè)主設(shè)備能夠控制總線。I2C的仲裁是基于**線與(Wired-AND)**邏輯的非破壞性仲裁。
時(shí)序細(xì)節(jié):
當(dāng)兩個(gè)或多個(gè)主設(shè)備同時(shí)發(fā)出開始條件,并開始傳輸?shù)刂泛蛿?shù)據(jù)時(shí),它們會(huì)同時(shí)監(jiān)測(cè)SDA線。
如果一個(gè)主設(shè)備試圖發(fā)送高電平(釋放SDA線,由上拉電阻拉高),但它檢測(cè)到SDA線是低電平(因?yàn)榱硪粋€(gè)主設(shè)備正在發(fā)送低電平),那么它就失去了仲裁。
失去仲裁的主設(shè)備將立即停止其傳輸,并將SCL和SDA線釋放為高電平,然后退回到從設(shè)備模式,監(jiān)聽總線直到下一個(gè)停止條件。
贏得仲裁的主設(shè)備則繼續(xù)其傳輸,絲毫不受影響。
仲裁過程通常發(fā)生在發(fā)送地址和數(shù)據(jù)字節(jié)期間:
開始條件:所有試圖通信的主設(shè)備同時(shí)發(fā)出開始條件。
地址傳輸:它們同時(shí)發(fā)送地址字節(jié)。第一個(gè)發(fā)送低電平(比特0)而另一個(gè)發(fā)送高電平(比特1)的主設(shè)備將失去仲裁。
R/W#位:如果地址相同,仲裁將繼續(xù)到R/W#位。
數(shù)據(jù)傳輸:如果地址和R/W#位都相同,仲裁將繼續(xù)到第一個(gè)數(shù)據(jù)字節(jié)。
仲裁是非破壞性的,這意味著贏得仲裁的主設(shè)備可以繼續(xù)其通信,而失去仲裁的主設(shè)備可以等待總線空閑后再次嘗試。這確保了在多主設(shè)備環(huán)境中通信的完整性。
4.3. 時(shí)鐘同步(Clock Synchronization - 詳細(xì)版)
盡管時(shí)鐘延長(zhǎng)是一種特殊情況下的時(shí)鐘控制,但I(xiàn)2C總線的SCL線本身也具備時(shí)鐘同步功能。所有主設(shè)備都會(huì)監(jiān)測(cè)SCL線的狀態(tài),即使它正在生成時(shí)鐘。
多主時(shí)鐘同步:當(dāng)多個(gè)主設(shè)備試圖生成SCL時(shí),它們都將SCL線拉低。只有當(dāng)所有主設(shè)備都將SCL線釋放后,SCL才能通過上拉電阻變高。這意味著所有主設(shè)備都會(huì)等待SCL真正變高,然后才能再次將其拉低。這種機(jī)制確保了所有主設(shè)備的時(shí)鐘步調(diào)一致,并且SCL的低電平周期總是等于最長(zhǎng)的低電平要求,高電平周期總是等于最短的高電平要求。
4.4. 一般呼叫地址(General Call Address)
I2C規(guī)范定義了一個(gè)特殊的7位地址0000000
(0x00)。這個(gè)地址被稱為一般呼叫地址。當(dāng)主設(shè)備向這個(gè)地址發(fā)送數(shù)據(jù)時(shí),總線上所有支持一般呼叫功能的從設(shè)備都會(huì)響應(yīng)并接收數(shù)據(jù)。
時(shí)序細(xì)節(jié):主設(shè)備發(fā)送開始條件,然后是地址0x00和R/W#位(通常為0,表示寫)。所有支持一般呼叫的從設(shè)備都會(huì)應(yīng)答。隨后主設(shè)備發(fā)送的數(shù)據(jù)會(huì)被所有這些設(shè)備接收。
用途:通常用于廣播信息,例如復(fù)位所有設(shè)備、設(shè)置統(tǒng)一的參數(shù)等。但并非所有從設(shè)備都支持一般呼叫。
4.5. SMBus兼容性
I2C是SMBus(System Management Bus)的基礎(chǔ)。SMBus在此基礎(chǔ)上添加了一些額外的功能和更嚴(yán)格的時(shí)序要求,例如超時(shí)機(jī)制和分組讀寫。許多現(xiàn)代微控制器和外設(shè)同時(shí)支持I2C和SMBus。雖然核心時(shí)序相似,但在設(shè)計(jì)或調(diào)試時(shí)應(yīng)注意它們之間的細(xì)微差別。
5. 信號(hào)完整性與電源注意事項(xiàng)
盡管I2C看起來很簡(jiǎn)單,但在實(shí)際應(yīng)用中,特別是在高速模式、長(zhǎng)距離傳輸或噪聲環(huán)境中,信號(hào)完整性問題可能導(dǎo)致通信錯(cuò)誤。
5.1. 上拉電阻選擇
上拉電阻的阻值對(duì)I2C總線的性能至關(guān)重要:
過大的電阻:會(huì)導(dǎo)致SDA和SCL線的上升時(shí)間過長(zhǎng)。這是因?yàn)榭偩€上的寄生電容(由PCB走線、連接器和設(shè)備引腳引起)需要通過上拉電阻充電才能達(dá)到高電平。如果上升時(shí)間超過I2C規(guī)范允許的最大值,數(shù)據(jù)采樣可能出錯(cuò)。
過小的電阻:會(huì)導(dǎo)致拉低電流過大。當(dāng)設(shè)備將SDA或SCL拉低時(shí),流過上拉電阻的電流會(huì)增大。如果電流過大,可能超出設(shè)備引腳的最大灌電流能力,導(dǎo)致設(shè)備損壞或信號(hào)失真。此外,這也會(huì)增加功耗。
計(jì)算上拉電阻: 通常,上拉電阻的計(jì)算需要考慮總線最大允許電流、總線電容和最大上升時(shí)間。公式通常涉及:
R_pullup=fracV_CC?V_OL(max)I_OL(max) (基于最大灌電流)
R_pulluplefracT_rise(max)C_bustimesln(fracV_CCV_CC?V_IL(max)) (基于最大上升時(shí)間)
其中:
V_CC 是總線電壓。
V_OL(max) 是輸出低電平的最大電壓。
I_OL(max) 是設(shè)備引腳的最大灌電流。
T_rise(max) 是SDA/SCL的最大允許上升時(shí)間(由I2C規(guī)范定義,取決于速率模式)。
C_bus 是總線總電容。
V_IL(max) 是輸入低電平的最大電壓。
5.2. 總線電容
總線電容是限制I2C總線速度和長(zhǎng)度的關(guān)鍵因素。它由PCB走線長(zhǎng)度、設(shè)備引腳電容、連接器和電纜等組成。I2C規(guī)范對(duì)不同速率模式下的總線最大電容有嚴(yán)格限制(例如,標(biāo)準(zhǔn)模式下最大400 pF)。過大的總線電容會(huì)導(dǎo)致信號(hào)上升/下降沿變慢,進(jìn)而導(dǎo)致通信錯(cuò)誤。
減小電容的方法:
縮短PCB走線長(zhǎng)度。
優(yōu)化PCB布局,減少平行走線和交叉。
選擇低電容的設(shè)備和連接器。
5.3. 噪聲抑制
I2C總線容易受到外部噪聲的干擾,尤其是在工業(yè)環(huán)境中。
濾波:可以在SDA和SCL線上增加小電容(幾pF到幾十pF)進(jìn)行低通濾波,以抑制高頻噪聲。但要注意,過大的電容會(huì)增加總線電容,影響速度。
地線回路:確保所有設(shè)備都有良好的地線連接,并最小化地線回路。
電源去耦:在每個(gè)I2C設(shè)備附近放置電源去耦電容,以確保穩(wěn)定的電源供電。
5.4. 串?dāng)_
當(dāng)SDA和SCL線平行布線過長(zhǎng)時(shí),可能會(huì)發(fā)生串?dāng)_,即SCL信號(hào)耦合到SDA線,反之亦然。這會(huì)導(dǎo)致數(shù)據(jù)失真。
避免平行布線:在PCB布局時(shí),盡量避免SDA和SCL線長(zhǎng)時(shí)間平行走線??梢越诲e(cuò)布線或在它們之間放置地線。
5.5. 信號(hào)電平兼容性
在多電壓系統(tǒng)中,如果I2C設(shè)備工作在不同的電壓域(例如,一個(gè)3.3V,一個(gè)5V),則需要進(jìn)行電平轉(zhuǎn)換。常用的方法是使用雙向電平轉(zhuǎn)換器,或者使用帶上拉電阻的MOSFET電路。
6. I2C 調(diào)試與常見問題
在實(shí)際開發(fā)中,I2C通信問題是常見的挑戰(zhàn)。理解其時(shí)序圖對(duì)于診斷這些問題至關(guān)重要。
6.1. 常見的I2C問題
設(shè)備無應(yīng)答(NACK):
地址錯(cuò)誤:檢查從設(shè)備地址是否正確(7位或10位,是否包含讀/寫位)。
設(shè)備未連接/上電:確認(rèn)從設(shè)備已正確連接并上電。
總線忙碌:在多主設(shè)備系統(tǒng)中,可能存在仲裁問題或另一個(gè)主設(shè)備正在使用總線。
設(shè)備忙碌:從設(shè)備可能正在執(zhí)行內(nèi)部操作,無法立即響應(yīng)(雖然時(shí)鐘延長(zhǎng)可以解決,但如果從設(shè)備沒有實(shí)現(xiàn)或?qū)崿F(xiàn)不當(dāng),也可能導(dǎo)致NACK)。
上拉電阻問題:上拉電阻值不正確,導(dǎo)致信號(hào)無法正確拉高。
SCL線問題:SCL線被從設(shè)備拉低,但從設(shè)備沒有及時(shí)釋放(卡死)。
固件錯(cuò)誤:主設(shè)備或從設(shè)備的I2C驅(qū)動(dòng)程序?qū)崿F(xiàn)有誤。
數(shù)據(jù)錯(cuò)誤/亂碼:
時(shí)鐘頻率不匹配:主設(shè)備和從設(shè)備對(duì)I2C時(shí)鐘頻率的支持范圍不一致。
總線電容過大:導(dǎo)致信號(hào)上升時(shí)間過長(zhǎng),數(shù)據(jù)采樣出錯(cuò)。
噪聲干擾:外部噪聲導(dǎo)致SDA或SCL信號(hào)失真。
線序錯(cuò)誤:SDA和SCL線接反。
讀寫方向錯(cuò)誤:主設(shè)備在讀寫操作中R/W#位設(shè)置錯(cuò)誤。
字節(jié)順序錯(cuò)誤:主設(shè)備或從設(shè)備處理數(shù)據(jù)字節(jié)順序有誤(MSB/LSB)。
時(shí)序違規(guī):不符合I2C時(shí)序規(guī)范,例如數(shù)據(jù)在SCL高電平期間發(fā)生變化。
總線掛死/SCL或SDA被拉低:
從設(shè)備卡住:從設(shè)備將SCL或SDA線拉低后,由于內(nèi)部錯(cuò)誤或軟件bug而未能釋放。這是最常見的I2C問題之一。
主設(shè)備未釋放:主設(shè)備未能正確釋放總線,例如在停止條件后沒有將SDA/SCL設(shè)置為高阻態(tài)。
硬件損壞:某個(gè)I2C設(shè)備或引腳短路到地。
不正確的電平轉(zhuǎn)換:電平轉(zhuǎn)換電路設(shè)計(jì)不當(dāng),導(dǎo)致某條線被永久拉低。
6.2. 調(diào)試工具與技巧
示波器:I2C調(diào)試的“瑞士軍刀”。使用示波器同時(shí)監(jiān)測(cè)SDA和SCL兩條線,可以清晰地看到所有時(shí)序事件。
觸發(fā):將示波器觸發(fā)設(shè)置為SCL的上升沿或下降沿,或SDA的特定電平變化,以便捕獲開始/停止條件或特定的數(shù)據(jù)位。
協(xié)議解碼:許多現(xiàn)代示波器具備I2C協(xié)議解碼功能,可以直接顯示總線上的地址、數(shù)據(jù)和應(yīng)答信息,大大簡(jiǎn)化調(diào)試。
測(cè)量上升/下降時(shí)間:檢查信號(hào)的上升/下降時(shí)間是否在I2C規(guī)范允許的范圍內(nèi)。
檢查噪聲:觀察信號(hào)線上是否存在毛刺或抖動(dòng)。
邏輯分析儀:如果需要長(zhǎng)時(shí)間捕獲I2C通信或同時(shí)監(jiān)測(cè)多個(gè)數(shù)字信號(hào),邏輯分析儀比示波器更具優(yōu)勢(shì)。它通常支持更長(zhǎng)的捕獲時(shí)間,并提供強(qiáng)大的協(xié)議解碼功能。
I2C總線分析儀/嗅探器:專門為I2C總線設(shè)計(jì),可以無源地監(jiān)聽總線通信,并提供易于理解的日志和錯(cuò)誤報(bào)告。
軟件調(diào)試:
逐步執(zhí)行:在微控制器固件中逐步執(zhí)行I2C驅(qū)動(dòng)程序代碼,觀察每一步后寄存器的狀態(tài)和引腳電平。
打印調(diào)試信息:在關(guān)鍵的I2C操作點(diǎn)打印出寄存器值、數(shù)據(jù)緩沖區(qū)內(nèi)容和狀態(tài)標(biāo)志,幫助定位問題。
I2C錯(cuò)誤處理:在固件中實(shí)現(xiàn)健壯的I2C錯(cuò)誤處理機(jī)制,例如超時(shí)檢測(cè)、總線復(fù)位和重新初始化。
總線復(fù)位(Bus Reset):當(dāng)I2C總線掛死(例如SCL或SDA被拉低)時(shí),可以嘗試執(zhí)行總線復(fù)位序列來恢復(fù)。標(biāo)準(zhǔn)I2C規(guī)范中沒有明確定義總線復(fù)位引腳,但可以通過特定的SCL和SDA序列來嘗試恢復(fù)。一種常見的方法是:
如果SDA被拉低,主設(shè)備可以嘗試生成9個(gè)SCL時(shí)鐘脈沖。在每個(gè)脈沖后檢查SDA是否被釋放。如果SDA在高電平,則可以發(fā)送停止條件。
如果SCL被拉低,通常需要復(fù)位從設(shè)備或上電重啟。
上拉電阻驗(yàn)證:確保上拉電阻阻值正確,并檢查它們是否正確連接。
總結(jié)
I2C時(shí)序圖是理解和成功使用I2C總線的基礎(chǔ)。從開始條件到停止條件,從地址尋址到數(shù)據(jù)傳輸,再到應(yīng)答和非應(yīng)答機(jī)制,每個(gè)環(huán)節(jié)都精確定義了SDA和SCL信號(hào)的電平變化和時(shí)序關(guān)系。深入理解標(biāo)準(zhǔn)模式、快速模式等不同速率下的具體時(shí)序參數(shù)(例如建立時(shí)間、保持時(shí)間、上升時(shí)間、下降時(shí)間等),對(duì)于設(shè)計(jì)健壯的I2C系統(tǒng)至關(guān)重要。
高級(jí)特性如時(shí)鐘延長(zhǎng)和總線仲裁則體現(xiàn)了I2C協(xié)議的靈活性和在復(fù)雜多主系統(tǒng)中的適應(yīng)性。而信號(hào)完整性、上拉電阻選擇和總線電容等硬件層面的考慮,則是確保I2C通信可靠性的前提。
最后,掌握I2C的調(diào)試技巧,特別是善用示波器和邏輯分析儀進(jìn)行波形分析和協(xié)議解碼,將極大地提高解決I2C通信問題的效率。通過對(duì)I2C時(shí)序圖的全面而深入的理解,您將能夠更自信地設(shè)計(jì)、實(shí)現(xiàn)和調(diào)試基于I2C的嵌入式系統(tǒng)。
責(zé)任編輯:David
【免責(zé)聲明】
1、本文內(nèi)容、數(shù)據(jù)、圖表等來源于網(wǎng)絡(luò)引用或其他公開資料,版權(quán)歸屬原作者、原發(fā)表出處。若版權(quán)所有方對(duì)本文的引用持有異議,請(qǐng)聯(lián)系拍明芯城(marketing@iczoom.com),本方將及時(shí)處理。
2、本文的引用僅供讀者交流學(xué)習(xí)使用,不涉及商業(yè)目的。
3、本文內(nèi)容僅代表作者觀點(diǎn),拍明芯城不對(duì)內(nèi)容的準(zhǔn)確性、可靠性或完整性提供明示或暗示的保證。讀者閱讀本文后做出的決定或行為,是基于自主意愿和獨(dú)立判斷做出的,請(qǐng)讀者明確相關(guān)結(jié)果。
4、如需轉(zhuǎn)載本方擁有版權(quán)的文章,請(qǐng)聯(lián)系拍明芯城(marketing@iczoom.com)注明“轉(zhuǎn)載原因”。未經(jīng)允許私自轉(zhuǎn)載拍明芯城將保留追究其法律責(zé)任的權(quán)利。
拍明芯城擁有對(duì)此聲明的最終解釋權(quán)。