I2C总线协议/地址详解
IIC總線
1.1. 概述
IIC開發于1982年,當時是為了給電視機內的CPU和外圍芯片提供更簡易的互連方式。電視機是最早的嵌入式系統之一,而最初的嵌入系統是使用內存映射(memory-mapped I/O)的方式來互連微控制器和外圍設備的。要實現內存映射,設備必須并行連入微控制器的數據線和地址線,這種方式在連接多個外設時需大量線路和額外地址解碼芯片,很不方便并且成本高。
為了節省微控制器的引腳和和額外的邏輯芯片,使印刷電路板更簡單,成本更低,位于荷蘭的Philips實驗室開發了IIC(Inter-Integrated Circuit),它是由數據線 SDA和時鐘線SCL兩根線構成的串行總線,可發送和接收數據。在CPU與被控IC之間、IC與IC之間進行雙向傳送
IIC數據傳輸速率有標準模式(100 kbps)、快速模式(400 kbps)和高速模式(3.4 Mbps),另外一些變種實現了低速模式(10 kbps)和快速+模式(1 Mbps)
1.2. 硬件結構
每一個I2C總線器件內部的SDA、SCL引腳電路結構都是一樣的,引腳的輸出驅動與輸入緩沖連在一起。其中輸出為漏極開路的場效應管、輸入緩沖為一只高輸入阻抗的同相器。這種電路具有兩個特點:
由于 SDA、SCL 為漏極開路結構,借助于外部的上拉電阻實現了信號的“線與”邏輯;
引腳在輸出信號的同時還能對引腳上的電平進行檢測,檢測是否與剛才輸出一致。為 “時鐘同步”和“總線仲裁”提供硬件基礎。
1.3. 數據類型
IIC數據傳輸的過程中,數據幀的大小固定為8位的字節,高位先發送。
主控器向被控器發送的信息種類有:
啟動信號、停止信號、7位地址碼、讀/寫控制位、10位地址碼(地址擴展)、數據字節、重啟動信號、應答信號、時鐘脈沖。
被控器向主控器發送的信息種類有:
應答信號、數據字節、時鐘低電平(時鐘拉伸)。
1.3.1. 總線空閑狀態
IIC總線的SDA和SCL兩條信號線同時處于高電平時,規定為總線的空閑狀態。此時各個器件的輸出級場效應管均處在截止狀態,即釋放總線,由兩條信號線各自的上拉電阻把電平拉高。
1.3.2. 啟動信號
SCL為高電平時,SDA由高電平向低電平跳變,開始傳送數據
1.3.3. 結束信號
SCL為高電平時,SDA由低電平向高電平跳變,結束傳送數據。
1.3.4. 重新開始信號
在IIC總線上,由主機發送一個開始信號啟動一次通信后,在首次發送停止信號之前,主機通過發送重新開始信號,可以轉換與當前從機的通信模式,或是切換到與另一個從機通信。當SCL為高電平時,SDA由高電平向低電平跳變,產生重新開始信號,它的本質就是一個開始信號
1.3.5. 應答信號
IIC總線上的所有數據都是以8位字節傳送的,發送器每發送一個字節,就在第9個時鐘脈沖期間釋放數據線,由接收器反饋一個應答信號。應答信號為低電平時,規定為有效應答位(ACK簡稱應答位),表示接收器已經成功地接收了該字節;應答信號為高電平時,規定為非應答位(NACK),一般表示接收器接收該字節沒有成功。
因此一個完整的字節數據傳輸需要9個時鐘脈沖。如果從機作為接收方向主機發送非應答信號,主機方就認為此次數據傳輸失敗;如果是主機作為接收方,在從機發送器發送完一個字節數據后,向從機發送了非應答信號,從機就認為數據傳輸結束,并釋放SDA線。不論是以上哪種情況都會終止數據傳輸,這時主機或是產生停止信號釋放總線或是產生重新開始信號,開始一次新的通信。
1.3.6. 數據傳送位
在IIC總線上傳送的每一位數據都有一個時鐘脈沖相對應(或同步控制),即在SCL串行時鐘的配合下,在SDA上逐位地串行傳送每一位數據。進行數據傳送時,在SCL呈現高電平期間,SDA上的電平必須保持穩定。只有在SCL為低電平期間,才允許SDA上的電平改變狀態。
1.3.7. 插入等待時間
如果被控器需要延遲下一個數據字節開始傳送的時間,則可以通過把時鐘線SCL電平拉低并且保持,使主控器進入等待狀態。一旦被控器釋放時鐘線,數據傳輸就得以繼續下去,這樣就使得被控器得到足夠時間轉移已經收到的數據字節,或者準備好即將發送的數據字節。
帶有CPU的被控器在對收到的地址字節做出應答之后,需要一定的時間去執行中斷服務子程序,來分析或比較地址碼,其間就把SCL線鉗位在低電平上,直到處理妥當后才釋放SCL線,進而使主控器繼續后續數據字節的發送
1.3.8. 總線沖突和總線仲裁
假如在某IIC總線系統中存在兩個主器件節點,分別記為主器件1和主器件2,其輸出數據分別為DATA1和DATA2,它們都有控制總線的能力,這就存在著發生總線沖突(即寫沖突)的可能性。
假設在某一瞬間兩者相繼向總線發出了啟動信號,鑒于:I2C總線的“線與”特性,使得在數據線SDA上得到的信號波形是DATA1和DATA2兩者相與的結果
在總線被啟動后,主器件1企圖發送數據“101……”,主器件2企圖發送數據“100……”。
兩個主器件在每次發出一個數據位的同時都要對自己輸出端的信號電平進行抽檢,只要抽檢的結果與它們自己預期的電平相符,就會繼續占用總線,總線控制權也就得不到裁定結果。
主器件1的第3位期望發送“1”,也就是在第3個時鐘周期內送出高電平。在該時鐘周期的高電平期間,主器件1進行例行抽檢時,結果檢測到一個不相匹配的電平“0”,這時主器件1只好決定放棄總線控制杈;因此,主器件2就成了總線的惟一主宰者,總線控制權也就最終得出了裁定結果,從而實現了總線仲裁的功能。
從以上總線仲裁的完成過程可以得出:仲裁過程主器件1和主器件2都不會丟失數據;各個主器件沒有優先級別之分,總線控制權是隨機裁定的。
系統實際上遵循的是“低電平優先”的仲裁原則,將總線判給在數據線上先發送低電平的主器件,而其他發送高電平的主器件將失去總線控制權
1.3.9. 時鐘同步
如果在某一I2C總線系統中存在兩個主器件節點,分別記為主器件1和主器件2,其時鐘輸出端分別為CLK1和CLK2,它們都有控制總線的能力。
假設在某一期間兩者相繼向SCL線發出了波形不同的時鐘脈沖序列CLK1和CLK2,在總線控制權還沒有裁定之前這種現象是可能出現的。
鑒于IIC總線的“線與”特性,使得時鐘線SCL上得到的時鐘信號波形,既不像主器件1所期望的CLK1,也不像主器件2所期望的CLK2,而是兩者進行邏輯與的結果。
CLKI和CLK2的合成波形作為共同的同步時鐘信號,一旦總線控制權裁定給某一主器件,則總線時鐘信號將會只由該主器件產生
1.3.10. 總線封鎖狀態
在特殊情況下,如果需要禁止所有發生在I2C總線上的通信活動,封鎖或關閉總線是一種可行途徑,只要掛接于該總線上的任意一個器件將時鐘線SCL鎖定在低電平上即可。
1.3.11. 高速模式
原理上講,使用上拉電阻來設置邏輯1會限制總線的最大傳輸速度。而速度是限制總線應用的因素之一。這也說明為什么要引入高速模式(3.4 Mbps)。在發起一次高速模式傳輸前,主設備必須先在低速的模式下(例如快速模式)發出特定的“High Speed Master”信號。為縮短信號的周期和提高總線速度,高速模式必須使用額外的I/O緩沖區。另外,總線仲裁在高速模式下可屏蔽掉。
1.3.12. 時鐘拉伸
在 IIC 通信中,主設備決定了時鐘速度。因為時鐘脈沖信號是由主設備顯式發出的。但是,當從設備沒辦法跟上主設備的速度時,從設備需要一種機制來請求主設備慢一點。這種機制稱為時鐘拉伸,而基于I2C結構的特殊性,這種機制得到實現。當從設備需要降低傳輸的速度的時候,它可以拉下時鐘線,逼迫主設備進入等待狀態,直到從設備釋放時鐘線,通信才繼續。
1.4. 通信過程
首先,主設備發一個START信號,然后其它設備開始監聽總線以準備接收數據。接著,主設備發送一個7位設備地址加一位的讀寫操作的數據幀。當所有從設備接收數據后,比對地址自己是否目標設備。如果比對不符,設備進入等待狀態,等待STOP信號的來臨;如果比對相符,設備會發送一個應答信號——ACK作回應。
當主設備收到應答后便開始傳送或接收數據。數據幀大小為8位。主設備發送數據,從設備應答;相反從設備發送數據,主設備應答。當數據傳送完畢,主設備發送一個STOP信號,向其它設備宣告釋放總線,其它設備回到初始狀態。
1.5. 尋址約定
為了消除IIC總線系統中主控器與被控器的地址選擇線,最大限度地簡化總線連接線,IIC總線采用了獨特的尋址約定,規定了開始信號后的第一個字節為尋址字節,用來尋址被控器件,并規定數據傳送方向。
在IIC總線系統中,尋址字節由七位地址位(它占據了D7-D1位)和一位方向位(為D0位)組成。方向位為0時表示主控器將數據寫入被控器,為 1時表示主控器從被控器讀取數據。主控器發送開始信號后,立即發送尋址字節,這時總線上的所有器件都將尋址字節中的7位地址與自己器件地址比較。如果兩者相同,則該器件認為被主控器尋址,并發送應答信號,被控器根據讀/寫位確定自身是作為發送器還是接收器。
主器件作為被控器時,其7位從地址在IIC總線地址寄存器中給定,為純軟件地址。而非單片機類型的外圍器件地址完全由器件類型與引腳電平給定。IIC總線系統中,沒有兩個從機的地址是相同的。主控器不應該傳輸一個和它本身的從地址相同的地址。
7位I2C總線可以掛接127個不同地址的I2C設備,0號”設備”作為群呼地址.
地址的分配方法有兩種:
含CPU的智能器件,地址由軟件初始化時定義,但不能與其它的器件有沖突
不含CPU的非智能器件,由廠家在器件內部固化,不可改變。
高7位為地址碼,其分為兩部分:
高4位屬于固定地址不可改變,由廠家固化的統一地址;
低三位為引腳設定地址,可以由外部引腳來設定(并非所有器件都可以設定);
常用IIC接口通用器件的器件地址是由種類型號以及尋址碼組成的,共7位。如格式如下:
D7 D6 D5 D4 D3 D2 D1 D0
器件類型由:D7-D4 共4位決定的。這是由半導公司生產時就已固定的了,也就是說這4位已是固定的。用戶自定義地址碼:D3-D1共3位。這是由用戶自己設置的,通常的作法如EEPROM這些器件是由外部IC的3個引腳所組合電平決定的(用常用的名字如A0,A1,A2)。這也就是尋址碼。所以為什么同一IIC總線上同一型號的IC只能最多共掛8片同種類芯片的原因了。
1.6. 寫過程
主機在檢測到總線為“空閑狀態”(即 SDA、SCL 線均為高電平)時,發送一個啟動信號“S”,開始一次通信的開始
主機接著發送一個命令字節。該字節由 7 位的外圍器件地址和 1 位讀寫控制位 R/W組成(此時 R/W=0為寫)
相對應的從機收到命令字節后向主機回饋應答信號 ACK(ACK=0)
主機收到從機的應答信號后開始發送第一個字節的數據
從機收到數據后返回一個應答信號 ACK
主機收到應答信號后再發送下一個數據字節
當主機發送最后一個數據字節并收到從機的 ACK 后,通過向從機發送一個停止信號P結束本次通信并釋放總線。從機收到P信號后也退出與主機之間的通信
注意:①主機通過發送地址碼與對應的從機建立了通信關系,而掛接在總線上的其它從機雖然同時也收到了地址碼,但因為與其自身的地址不相符合,因此提前退出與主機的通信;②主機的一次發送通信,其發送的數據數量不受限制。主機是通過 P 信號通知發送的結束,從機收到 P 信號后退出本次通信;③主機的每一次發送后都是通過從機的 ACK 信號了解從機的接收狀況,如果應答錯誤則重發。
1.7. 讀過程
主機發送啟動信號后,接著發送命令字節(其中 R/W=1)
對應的從機收到地址字節后,返回一個應答信號并向主機發送數據
主機收到數據后向從機反饋一個應答信號
從機收到應答信號后再向主機發送下一個數據
當主機完成接收數據后,向從機發送一個“非應答信號(ACK=1)”,從機收到ACK=1 的非應答信號后便停止發送
主機發送非應答信號后,再發送一個停止信號,釋放總線結束通信
注意:主機所接收數據的數量是由主機自身決定,當發送“非應答信號/A”時從機便結束傳送并釋放總線(非應答信號的兩個作用:前一個數據接收成功,停止從機的再次發送)。
1.8. 總線死鎖原因分析
I2C總線寫操作過程中,主機在產生啟動信號后控制SCL產生8個時鐘脈沖,然后拉低SCL信號為低電平,在這個時候,從機輸出應答信號,將SDA信號拉為低電平。如果這個時候主機異常復位,SCL就會被釋放為高電平。此時,如果從機沒有復位,就會繼續I2C的應答,將SDA一直拉為低電平,直到SCL變為低電平,才會結束應答信號。而對于主機來說,復位后檢測SCL和SDA信號,如果發現SDA信號為低電平,則會認為I2C總線被占用,會一直等待SCL和SDA信號變為高電平。這樣,主機等待從機釋放SDA信號,而同時從機又在等待主機將SCL信號拉低以釋放應答信號,兩者相互等待,I2C總線進人一種死鎖狀態。同樣,當I2C進行讀操作時,從機應答后輸出數據,如果在這個時刻主機異常復位而此時從機輸出的數據位正好為0,也會導致I2C總線進入死鎖狀態。
解決方案通常有如下幾種:
將從機的電源設計為可控,當發生總線死鎖的時將從機復位
可以在從機的程序中加入監測功能,如果總線長時間被拉低則釋放對總線的控制
在主機中增加I2C總線恢復程序。每次主機復位后,如果檢測到SDA被拉低,則控制SCL產生<=9個時鐘脈沖(針對8位數據的情況),每發送一個時鐘脈沖就檢測SDA是否被釋放,如果SDA已經被釋放就再模擬產生一個停止信號,這樣從機就可以完成被掛起的讀寫操作,從死鎖狀態中恢復過來。這種方法有一定的局限性,因為大部分主機的I2C模塊由內置的硬件電路來實現,軟件并不能夠直接控制SCL信號模擬產生需要的時鐘脈沖
1.9. 地址擴展
任何IIC設備都有一個7位地址,理論上,現實中只能有127種不同的IIC設備。實際上,已有IIC的設備種類遠遠多于這個限制,在一條總線上出現相同的地址的IIC設備的概率相當高。為了突破這個限制,很多設備使用了雙重地址——7位地址加引腳地址(external configuration pins)。IIC 標準也預知了這種限制,提出10位的地址方案。
10位的地址方案對 IIC協議的影響有兩點:
地址幀為兩個字節長,原來的是一個字節;
第一個字節前五位最高有效位用作10位地址標識,約定是“11110”。
1.10. IIC總線典型應用
IIC設備典型應用:
物理結構上,IIC系統由一條串行數據線SDA和一條串行時鐘線SCL組成。主機按一定的通信協議向從機尋址和進行信息傳輸。在數據傳輸時,由主機初始化一次數據傳輸,主機使數據在SDA線上傳輸的同時還通過SCL線傳輸時鐘。信息傳輸的對象和方向以及信息傳輸的開始和終止均由主機決定。
每個器件都有一個唯一的地址,而且可以是單接收的器件(例如:LCD驅動器)或者可以接收也可以發送的器件(例如:存儲器)。發送器或接收器可以在主模式或從模式下操作,這取決于芯片是否必須啟動數據的傳輸還是僅僅被尋址。
以上原文鏈接:https://blog.csdn.net/u010650845/article/details/73467586
關于7,8,10位地址的講解
7位尋址
在7位尋址過程中,從機地址在啟動信號后的第一個字節開始傳輸,該字節的前7位為從機地址,第8位為讀寫位,其中0表示寫,1表示讀。
圖1:7位尋址。I2C總線規范規定,標準模式I2C,從機地址為7位長,其次是讀/寫位。
任何I2C設備都必須遵循這個標準,USB2XXX傳輸的從機地址即為這7bit地址,不包含讀寫位,讀寫位會根據不同的函數自動添加進去。
保留地址
I2C規范保留了兩組和8個地址,1111XXX和0000XXX。這些地址用于特殊用途。下表已被取自 I2C規范(2000年)。
| 0000 0000 | 呼叫地址 |
| 0000 0001 | 起始字節 |
| 0000 001X | CBUS地址 |
| 0000 010X | 保留供不同的總線格式 |
| 0000 011X | 保留將來用 |
| 0000 1XXX | HS模式主機碼 |
| 1111 0XXX | 10位從機地址 |
| 1111 1XXX | 保留將來用 |
8位地址
一些廠商在提供從機地址的時候說的是包含了讀寫位的8bit地址,比如他說寫地址為0x92,讀地址為0x93,如下圖所示
這種情況下,你只需要將這個地址的前7bit提取出來,然后傳入USB2XXX的接口函數即可,比如為0x49。
還有一種方式可以判斷廠商提供的地址是7bit模式地址還是8bit地址模式的地址,7bit地址模式下,地址的取值范圍在0x07到0x78之間,若超過了這個范圍,那么這個地址可能就是8bit地址。
圖3:有效的7bit地址范圍
10位尋址
I2C總線的10bit尋址和7bit尋址是兼容的,這樣就可以在同一個總線上同時使用7bit地址和10bit地址模式的設備,在進行10bit地址傳輸時,第一字節是一個特殊的保留地址來指示當前傳輸的是10bit地址。
在使用USB2XXX傳輸10bit地址模式的時候,只需要在初始化的時候配置為10bit地址模式,然后再調用讀寫數據函數的時候傳入正確的10bit地址即可。
I2C讀寫地址結論:
I2C設備的寫地址 = I2C設備地址 << 1
I2C設備的讀地址 = (I2C設備地址 << 1) + 1
例如:
#define MAX_17040_BATTERY_I2C_ADDR (0x36)
#define MAX_17040_BATTERY_WRITE_ADDR (MAX_17040_BATTERY_I2C_ADDR << 1)
#define MAX_17040_BATTERY_READ_ADDR ((MAX_17040_BATTERY_I2C_ADDR << 1) + 1)
AT24C02有三根地址線來進一步確定I2C設備的地址。說是進一步確定,是因為對于這類的I2C設備來說
其地址的一部分已經是確定好了的。
例如:數據手冊上寫道:
Device Address
1K/2K 1 0 1 0 A2 A1 A0 R/W
也就是說對于改I2C設備來說,地址的高8位已經確定了為1010,
而低四位則有A2 ----A0來確定 R/W來確定讀寫方向,讀還是寫。
例如,我們把A0 --A3全部拉低,則該設備的地址為0xA0.
在ARM中,讀寫方向是用寄存器的單獨一位來確定的,有一個7位的域用來保存設備地址。
所以該I2C設備在ARM I2C總線上的地址為
0xA0 右移一位 0x50.
如果A0–A2 有其他選擇的話,則可以根據上述原則求得設備地址。
I2C設備地址
協議格式中第一個字節(為slave address)由7位地址和一位R/W讀寫位組成的,這字節是個器件地址。
常用IIC接口通用器件的器件地址是由種類型號,及尋址碼組成的,共7位。
如格式如下:
D7 D6 D5 D4 D3 D2 D1 D0
1、器件類型:D7-D4 共4位決定的。這是由半導公司生產時就已固定此類型的了,也就是說這4位已是固定的。
2、用戶自定義地址碼:D3-D1共3位。這是由用戶自己設置的,通常的作法如EEPROM這些器件是由外部IC的3個引腳所組合電平決定的(用常用的名字如A0,A1,A2)。這也就是尋址碼。所以為什么同一IIC總線上同一型號的IC只能最多共掛8片同種類芯片的原因了。
3、最低一位就是R/W位,,“0”表示寫,“1”表示讀(通常讀寫信號中寫上面有一橫線,表示低電平)。所以I2C設備通常有兩個地址,即讀地址和寫地址。
引用<<i2c 源代碼情景分析>>里的話:“i2c 設備的7 位地址是就當前i2c 總線而言的,是“相對地址”。不同的i2c 總線上的設備可以使用相同的7 位地址,但是它們所在的i2c 總線不同。所以在系統中一個i2c 設備的“絕對地址”由二元組(i2c 適配器的ID 和設備在該總線上的7 位地址)表示?!?#xff0c;所以這個函數的作用主要是排除同一i2c總線上出現多個地址相同的設備。
總結
以上是生活随笔為你收集整理的I2C总线协议/地址详解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Idea新建modules后无法自动导入
- 下一篇: 40幅五彩缤纷的秋天风景摄影作品欣赏(上