據非官方統計,90%電子行業的公眾號都介紹過3種串行通訊協議:UART、SPI和I2C。這3種串行協議也是電子開發行業最常用的協議。前面介紹了串口通訊協議及其FPGA實現,SPI協議。本篇文章介紹I2C通訊協議及其FPGA實測波形。
1.I2C是什么
在消費電子,工業電子等領域,會使用各種類型的芯片,如微控制器,電源管理,顯示驅動,傳感器,存儲器,轉換器等,他們有着不同的功能,有時需要快速的進行數據的交互,為了使用最簡單的方式使這些芯片互聯互通,於是I2C誕生了,I2C(Inter-Integrated Circuit)是一種通用的總線協議。它是由Philips(飛利浦)公司,現NXP(恩智浦)半導體開發的一種簡單的雙向兩線制總線協議標准。
對於硬件設計人員來說,只需要2個管腳,極少的連接線和面積,就可以實現芯片間的通訊,對於軟件開發者來說,可以使用同一個I2C驅動庫,來實現實現不同器件的驅動,大大減少了軟件的開發時間。極低的工作電流,降低了系統的功耗,完善的應答機制大大增強通訊的可靠性。
2.5種速率
I2C協議可以工作在以下5種速率模式下,不同的器件可能支持不同的速率。
標准模式(Standard):100kbps
快速模式(Fast):400kbps
快速模式+(Fast-Plus):1Mbps
高速模式(High-speed):3.4Mbps
超快模式(Ultra-Fast):5Mbps(單向傳輸)
【bps:bit/s,即SCL的頻率】
其中超快模式是單向數據傳輸,通常用於LED、LCD等不需要應答的器件,和正常的I2C操作時序類似,但是只進行寫數據,不需要考慮ACK應答信號。
在I2C協議的官方文檔NXP_UM10204_I2C-bus specification and user manual_Rev.6,超快模式和其他模式在3.2和3.1章節分別進行介紹。
3.4種信號
I2C協議最基礎的幾種信號:起始、停止、應答和非應答信號。
起始信號
I2C協議規定,SCL處於高電平時,SDA由高到低變化,這種信號是起始信號。
停止信號
I2C協議規定,SCL處於高電平,SDA由低到高變化,這種信號是停止信號。
數據有效性
I2C協議對數據的采樣發生在SCL高電平期間,除了起始和停止信號,在數據傳輸期間,SCL為高電平時,SDA必須保持穩定,不允許改變,在SCL低電平時才可以進行變化。
應答信號****
I2C最大的一個特點就是有完善的應答機制,從機接收到主機的數據時,會回復一個應答信號來通知主機表示“我收到了”。
應答信號出現在1個字節傳輸完成之后,即第9個SCL時鍾周期內,此時主機需要釋放SDA總線,把總線控制權交給從機,由於上拉電阻的作用,此時總線為高電平,如果從機正確的收到了主機發來的數據,會把SDA拉低,表示應答響應。
使用MCU、FPGA等控制器實現時,需要在第9個SCL時鍾周期把SDA設置為高阻輸入狀態,如果讀取到SDA為低電平,則表示數據被成功接收到,可以進行下一步操作。
非應答信號
當第9個SCL時鍾周期時,SDA保持高電平,表示非應答信號。
非應答信號可能是主機產生也可能是從機產生,產生非應答信號的情況主要有以下幾種:
I2C總線上沒有主機所指定地址的從機設備
從機正在執行一些操作,處於忙狀態,還沒有准備好與主機通訊
主機發送的一些控制命令,從機不支持
主機接收從機數據時,主機產生非應答信號,通知從機數據傳輸結束,不要再發數據了
4.讀寫時序
向指定寄存器地址寫入指定數據操作時序:
從指定寄存器地址讀取數據操作時序:
注意,讀數據時有兩次起始信號。
5.7位和10位地址
大多數I2C器件支持7位地址模式,有一些器件還支持10位地址,而且兩種類型的器件可以連接在同一個I2C總線上,目前10位地址的器件還沒有被廣泛使用。
主機發送,從機接收。使用10位地址進行寫時序:
主機接收,從機發送。使用10位地址進行讀時序:
6.I2C保留字節
I2C讀寫時起始位之后的第一個字節,除了廠商指定的設備地址外,還有一些保留字節,主要有兩組0000 xxx和1111 xxx,保留字節的含義:
上述的10位地址模式,就是使用到了最后一種保留字節。
第一種廣播模式,可以通過寫入第二個字節06h來復位I2C總線上所有的從機器件。具體操作時序可以查看文檔NXP_UM10204_I2C-bus specification and user manual_Rev.6:3.1.12 Reserved addresses章節有詳細介紹。其中device ID控制字(1111 1xx1),可以讀取I2C器件內部的24位器件ID,通過對照NXP I2C協議器件列表可以查詢到器件所屬的廠商和型號。
設備ID與器件廠商對應表
7.FPGA實測I2C波形
FPGA實現UART、SPI、I2C等串行時序,最常用的實現方式就是狀態機大法,將各個步驟分解為各個狀態,然后根據不同的狀態去控制輸出或讀取輸入,細節方面需要考慮數據的對齊、建立和保持時間、一些異常情況時狀態的跳轉,不能進入死循環,或卡死在某一個狀態。
I2C控制狀態機狀態定義:
//general
S0_IDLE = 0,
S1_START1 = 1,
S2_CTRL_BYTE1 = 2,
S3_ACK1 = 3,
S4_ADDR = 4,
S5_ACK2 = 5,
//write: 0-1-2-3-4-5->6-7-13-14
S6W_DATA = 6,
S7W_ACK3 = 7,
//read: 0-1-2-3-4-5->8-9-10-11-12-13-14
S8R_START2 = 8,
S9R_CTRL_BYTE2 = 9,
S10R_ACK3 = 10,
S11R_DATA = 11,
S12R_NACK = 12,
//general
S13_STOP = 13,
S14_DONE = 14,
S15_ERR = 15;
注意SDA雙向端口的方向控制。
output eeprom_scl,
inout eeprom_sda,
localparam DIR_IN = 1'b0;
localparam DIR_OUT = !DIR_IN;
reg dir;
reg i2c_sda;
reg i2c_scl;
assign eeprom_scl = i2c_scl;
assign eeprom_sda = (dir == DIR_OUT) ? i2c_sda : 1'bz;
wire sda_in = eeprom_sda;
SDA應該在第9個SCL時鍾周期設置為輸入狀態:
下圖的波形是使用Xilinx FPGA對AT24C1024的驅動,使用片上邏輯分析儀ChipScope抓取的實際波形,AT24C1024B存儲空間為1024K Bit = 131072 Byte,存儲單元地址位寬為17位。
AT24C1024B寫時序:
AT24C1024B讀時序:
SPI和I2C的對比
I2C是半雙工,SPI是全雙工。
I2C支持多主多從模式,而SPI只能有一個主機。
從GPIO占用上來看,I2C占用更少的GPIO,更節省資源。
I2C有應答響應機制,數據可靠性更高,SPI沒有應答機制。
I2C速率不會太高,最高速率3.4Mbps,SPI可以達到很高的速率。
I2C通過器件地址來選擇從機,從機數量的增加不會導致GPIO的增加,而SPI通過CS選擇從機,每增加一個從機就要多占用一個GPIO。
SPI協議在SCLK邊沿進行數據采樣,I2C在SCL高電平期間進行數據采樣。
兩者大多都應用於板內器件短距離通訊。
官方標准文檔下載
目前網上比較詳細的介紹I2C文檔主要有以下3個:
-
I2C官方標准文檔_UM10204
I2C的官方文檔是原飛利浦(Philips)半導體事業部,現恩智浦(NXP)半導體發布的UM10204文檔,全文共64頁,是目前最權威最詳細的I2C協議介紹文章,最新版本Rev. 6發布於20140404,UM10204_4 April 2014: I2C-bus specification and user manual_Rev.6 -
TI:理解I2C文檔_SLVA704
TI在2015年發布了一篇SLVA704文檔, 全文共8頁,精簡的概括了I2C協議的電氣特性,操作時序,讀寫時序等,比較適合I2C入門學習。 -
ZLG:I2C總線規范中文版
這篇文檔發布於2000年左右,是對飛利浦官方文檔UM10204_v2.1的翻譯。
I2C協議文檔只是最基礎的文檔,具體寄存器讀寫操作等操作,還是要結合所使用芯片的數據手冊來使用。