目錄
1. I2C介紹
1.1 常用術語
1.2 I2C物理層
1.3 I2C協議層
1.3.1 數據有效性規定
1.3.2 起始和停止信號
1.3.3 應答響應
1.3.4 總線的尋址地址
1.3.5 數據傳輸
1. I2C介紹
I2C(Inter-Integrated Circuit)總線是一種兩線式串行總線,用於連接微控制器及其外圍設備,是同步通信的一種特殊形式,具有接口線少,控制方式簡單,器件封裝形式小,通信速率較高等優點
I2C 總線只有兩根雙向信號線,一根是數據線 SDA,另一根是時鐘線 SCL,由於其管腳少,硬件實現簡單,可拓展性強等特點,被廣泛的使用在各大集成芯片內
1.1 常用術語
I2C 通信設備:採用 I2C總線協議進行數據傳輸的電子設備 / 芯片
主機:啓動數據傳送併產生時鐘信號的設備
從機:被主機尋址的器件
主模式:用 I2CNDAT 支持自動字節計數的模式,位 I2CRM,位I2CSTT,I2CSTP控制數據的接收和發送
從模式:發送和接收操作都是由I2C模塊自動控制的
仲裁:在有多個主機同時嘗試控制總線但只允許其中一個控制總線並使傳輸不被破壞的過程
同步:兩個或多個器件同步時鐘信號的過程
發送器:發送數據到總線的器件
接收器:從總線接收數據的器件
多主機:同時有兩個及兩個以上的主機嘗試控制總線但不破壞傳輸
1.2 I2C物理層
I2C 通信設備常用的連接方式如下所示:
物理層有如下特點:
①總線支持多設備:”總線“是指多個設備共用的信號線。在一個I2C通訊總線中,可連接多個I2C通訊設備,支持多個通訊主機及多個通訊從機
②一個I2C總線只使用兩條總線線路,一條雙向串行數據線(SDA),一條串行時鐘線(SCL)。數據線用來表示數據,時鐘線用於數據收發同步
③每個連接到總線的設備都有一個獨立的地址,主機可以利用這個地址進行不同設備間的訪問
④總線通過上拉電阻接到電源。當 I2C 設備空閒時,會輸出高阻態,而當所有設備都空閒,都輸出高阻態時,由上拉電阻把總線拉成高電平
⑤多個主機同時使用總線時,為了防止數據衝突,會用仲裁的方式決定由哪個設備佔用總線
⑥具有三種傳輸模式:標準模式傳輸速率為100kbit/s,快速模式為400kbit/s,高速模式為3.4Mbit/s,但目前大多I2C設備尚不支持高速模式
⑦連接到相同總線的IC數量受到總線的最大電容 400pF 限制
1.3 I2C協議層
I2C協議定義了通信的起始信號、停止信號、數據有效性、響應、仲裁、時鐘同步和地址廣播等環節
1.3.1 數據有效性規定
I2C總線進行數據傳送時,時鐘信號為高電平期間,數據線上的數據必須保持穩定
只有在時鐘線上的信號為低電平期間,數據線上的高/低電平狀態才允許變化
每次數據傳輸都以字節為單位,每次傳輸的字節數不受控制
1.3.2 起始和停止信號
SCL為高電平期間,SDA線 由高電平向低電平的變化表示起始信號
SCL為高電平期間,SDA線 由低電平向高電平的變化表示終止信號
起始信號和終止信號都是由主機發出的,在起始信號產生後,總線就處於被佔用的狀態
終止信號產生後,總線就處於空閒狀態
1.3.3 應答響應
每當發送器件傳輸完一個字節的數據後,後面必須緊跟一個校驗位【該校驗位是接收端控制SDA來實現的(SDA,SCL都是雙向信號線)】,以提醒發送端數據我這邊已接收完成,可以繼續進行數據傳送,這個校驗位就是數據/地址傳輸過程中的響應;
響應包括”應答(ACK)“和”非應答(NACK)“兩種信號:
通信中 “應答位(ACK)” 的交互規則固定:主機發送完 1 字節數據(地址或數據)後,會釋放 SDA 線的控制權,然後在第 9 個時鐘週期內,由從機控制 SDA 線狀態,完成應答或不應答操作。
左側灰色區域:起始信號(S)
I2C 的起始信號是通信的 “開場白”,規則是:
- 當
SCL(主機時鐘)處於高電平時,SDA(主機數據線)出現從高到低的下降沿(圖中 SDA 的黑色箭頭就是這個動作)。 - 這個信號的作用是告訴總線上的所有從機:“我(主機)要開始發數據了,準備接收”。
SCL 的 1~8 時鐘週期:主機發送 8 位數據
I2C 中數據是按字節(8 位)傳輸的,這 8 個時鐘週期對應 1 字節數據(可能是從機地址、讀寫指令,或是實際數據):
SCL由主機控制,每一個時鐘的高電平期間,從機會採樣SDA上的電平(高 = 1,低 = 0),所以主機要在SCL低電平期間提前把下一位數據的電平準備好,保證SCL高電平時SDA穩定(圖中主機 SDA 的波形在每個 SCL 週期內是平穩的,就是為了讓從機準確採樣)。- 這一步是 “主機→從機” 的單向數據傳輸。
第 9 個時鐘週期:應答位(ACK/NACK)
這是 I2C 的 “反饋環節”,規則是:
- 主機發完 8 位數據後,會在第 9 個時鐘週期釋放 SDA 的控制權(不再主動控制 SDA 電平);
- 此時由從機控制 SDA:
- 若從機拉低 SDA(圖中 “應答” 標註的波形),則表示 “我收到這字節數據了”,這叫應答位(ACK);
- 若從機不操作 SDA(SDA 因上拉電阻保持高電平,圖中 “非應答” 標註的狀態),則表示 “我沒收到 / 無法處理”,這叫非應答位(NACK)。
每一個字節必須保證是8位長度,數據傳送時,先傳送最高位(MSB),每一個被傳送的字節後面都必須跟隨一個應答位(即一幀共有9位)
如果從機由於某種故障等原因無法應答時,主機檢測到不應答後,為避免總線阻塞,通常會主動發送終止信號,釋放總線資源
如果從機對主機進行了應答,但在數據傳送一段時間後無法繼續接收更多的數據時(即從機接收能力不足),從機可以通過對無法接收的第一個數據字節的”非應答“(應答位的本質:“對當前字節的接收結果負責”)通知主機,主機則應發出終止信號以結束數據的繼續傳送(主機每傳 1 個字節,從機都在第 9 個時鐘週期發 “應答(ACK)”,表示 “我收到了,繼續傳下一個”。)
當主機接收數據時(即主機讀取從機數據,核心是 “讀操作時,應答位的控制權轉到了主機手裏”),主機收最後一個字節,發 “非應答”,即主機收完最後一個字節後,不再需要更多數據了 —— 此時主機在第 9 個時鐘週期釋放 SDA(因為總線有上拉電阻,SDA 會保持高電平),這就是 “非應答(NACK)”,告訴從機:“這是最後一個了,別發了”。從機收到這個 “非應答”,就停止發送數據,並完全釋放 SDA 線的控制權,主機確認 SDA 被釋放後,發送 “終止信號”(SCL 高電平時,SDA 從低變高),結束整個讀傳輸。
簡單地説,讀操作時,主機是 “收數據的一方”,用 “最後一個字節後的非應答” 喊 “停”,從機停了之後,主機再收尾。
注意:
① 從機無需主動置高 SDA,而是不主動拉低 SDA。由於總線有上拉電阻,SDA 會自然保持高電平,這就是 I2C 協議中的非應答位(NACK);
② 從機的 “主動動作” 僅出現在應答時:應答時從機會主動拉低 SDA 線,使第 9 個時鐘週期內 SDA 保持低電平;不應答時,從機完全釋放 SDA,總線依靠上拉電阻回到高電平,並非從機主動輸出高電平信號。
1.3.4 總線的尋址地址
按從機地址位數可分為兩種,一種是 7 位,另一種是 10 位
採用 7 位的尋址字節(即起始信號後的第一個字節)的定義如下:
D7-D1 位組成從機的地址。
D0 位是數據傳送方向位,0:表示主機向從機寫數據;1:表示主機由從機讀數據
10位 尋址和 7位 尋址兼容,而且可以結合使用。10位 尋址不會影響已有的7位尋址,有7位和10位地址的器件可以連接到相同的I2C總線
I2C 總線支持多從機掛載(比如 51 單片機總線上同時接了 AT24C02 存儲芯片、BH1750 光照傳感器),每個從機都有唯一的 7 位地址(部分設備支持 10 位地址,但入門場景常用 7 位)
現以 7位 尋址為例:
主機發起通信時,第一個發送的字節是 “7 位從機地址 + 1 位 R/W 位”,此時:
- 總線上所有從機都會 “監聽” 這字節的前 7 位;
- 每個從機把這 7 位和自己的地址對比:
- 地址匹配的從機:判定 “主機在找我”,會在後續的應答位發 “應答(ACK)”,準備和主機通信;
- 地址不匹配的從機:判定 “和我無關”,會忽略後續的所有數據 / 時鐘信號,進入 “靜默狀態”。
“R/W 位”:決定從機是 “收數據” 還是 “發數據”
地址字節的第 8 位(最後 1 位)就是 R/W 位,它的作用是定義本次通信的方向:
- 若 R/W 位為
0:表示 “寫(Write)”,此時從機是從機接收器—— 主機要給從機發送數據(比如 51 單片機給 AT24C02 寫存儲內容); - 若 R/W 位為
1:表示 “讀(Read)”,此時從機是從機發送器—— 從機要給主機發送數據(比如 51 單片機讀 BH1750 的光照數據)。
再來説説從機地址
I2C 從機地址的硬件設計核心是通過 “固定地址 + 可編程地址” 的組合,解決 “同一型號從機多設備並聯” 的問題;
I2C 從機的 7 位地址(入門場景常用)本質是廠商預設的固定位 + 用户可配置的可編程位組成,兩者分工明確:
固定部分:芯片出廠時由廠商固化在內部,同一型號的從機固定部分完全相同,作用是區分 “不同類型的器件”。
可編程部分:芯片引腳引出的地址配置位(通常標註為 A0/A1/A2),用户可通過硬件接線(接 VCC 或 GND)設置其電平(高 = 1,低 = 0),從而改變這幾位的地址值。作用是區分 “同一型號的不同個體”,避免總線上相同型號的從機地址衝突。
注意:
- 可編程部分的設置是硬件層面的,一旦接線完成,地址就固定了,不能通過軟件修改;
- 同一總線上,所有從機的完整地址必須唯一,哪怕是不同型號的器件,也不能設置相同地址;
- 部分芯片的可編程引腳如果懸空,可能會有不確定電平,建議項目中明確接 VCC 或 GND,避免地址錯亂。
1.3.5 數據傳輸
I2C總線上傳送的數據信號是廣義的,既包括地址信號,又包括真正的數據信號
主機產生起始信號,起始信號後必須傳送一個從機的地址(7位),第8位是數據的傳送方向位(R/W),用 0 表示主機發送(寫)數據,1 表示主機接收(讀)數據。
每次數據傳送總是由主機產生的終止信號結束,若主機希望繼續佔用新的數據傳送,馬上再次發出起始信號對另一從機進行尋址
在總線的一次數據傳送過程中,可以有以下幾種組合方式:
陰影部分:主機向從機傳送數據 無陰影部分:從機向從主機傳送數據
A:表示應答 A非:表示非應答(高電平)
S:起始信號 P:終止信號
① 主機向從機發送數據,數據傳送方向在整個傳送過程中不變
②主機發送第一個字節後,立即從從機讀取數據
③ 在傳送過程中,當需要改變傳送信號(從 “主機→從機寫數據” 切換為 “從機→主機讀數據”)時,起始信號和從機地址都被重複產生一次,但兩次讀/寫方向位正好相反
主機先發起始信號 S + 從機地址 + 寫方向位 0,給從機傳數據(比如 AT24C02 的存儲地址);當需要切換成 “讀數據” 時,不發終止信號,直接重複發起始信號 S + 同一個從機地址 + 讀方向位 1;這樣就完成了 “傳送方向的改變”,同時保持總線一直被主機佔用(避免被其他設備干擾)。