01
IIC基礎知識
集成電路總線 (Inter-Intergrated Circuit),通常稱作IICBUS,簡稱為IIC,是一種采用多主從結(jié)構(gòu)的串行通信總線。
IIC由PHILIPS公司于1980年推出,利用該總線可實現(xiàn)多主機系統(tǒng)所需的裁決和高低速設備同步等功能。
IIC串行總線一般有兩根信號線,分別是時鐘線SCL和數(shù)據(jù)線SDA,所有IIC總線各設備的串行數(shù)據(jù)SDA接到總線SDA上,時鐘線SLC接到總線SCL上。
雙向串行數(shù)據(jù)SDA:輸出電路用于向總線發(fā)送數(shù)據(jù),輸入電路用于接收總線上的數(shù)據(jù);
雙向時鐘數(shù)據(jù)SCL:輸出電路用于向總線發(fā)送時鐘信號,輸入電路用于檢測總線時鐘電平以決定下次時鐘脈沖電平時間。
各設備與總線相連的輸出端采用高阻態(tài)以避免總線信號的混亂,通常采用漏極開路輸出或集電極開路輸出。總線空閑時,各設備都是開漏輸出,通常可采用上拉電阻使總線保持高電平,而任一設備輸出低電平都將拉低相應的總線信號。
IIC總線上的設備可分為主設備和從設備兩種:主設備有權(quán)利主動發(fā)起/結(jié)束一次通信;從設備只能被動響應。
所有連接在IIC總線上的設備都有各自唯一的地址(原地址位寬為7bits,改進后采用10bits位寬),每個設備都可以作為主設備或從設備,但是同一時刻只能有一個主設備控制。
如果總線上有多個設備同時啟用總線,IIC通過檢測和仲裁機制解決傳輸沖突。IIC允許連接的設備傳輸速率不同,多臺設備之間時鐘信號的同步過程稱為同步化。
02
IIC傳輸協(xié)議
2.1 IIC協(xié)議模式
IIC協(xié)議為半雙工模式,同一條數(shù)據(jù)線上完成讀/寫操作,不同操作時的數(shù)據(jù)幀格式可分為寫操作、讀操作、讀寫操作。
2.1.1 寫操作數(shù)據(jù)幀格式
主機向從機寫數(shù)據(jù)的數(shù)據(jù)幀格式如下:
白色為主機發(fā)送數(shù)據(jù),灰色為從機發(fā)送數(shù)據(jù)。
- 主機發(fā)送開始信號S;
- 主機發(fā)送地址數(shù)據(jù)ADDR;
- 主機發(fā)送寫信號0;
- 從機響應主機寫信號ACK;
- 主機發(fā)送數(shù)據(jù)信息DATA;
- 從機響應主機發(fā)送數(shù)據(jù)ACK;
- 循環(huán)5 6步驟可完成主機向從機連續(xù)寫數(shù)據(jù)過程;
- 主機發(fā)送結(jié)束信號P.
2.1.2 讀操作數(shù)據(jù)幀格式
主機從從機讀數(shù)據(jù)的數(shù)據(jù)幀格式如下:
白色為主機發(fā)送數(shù)據(jù),灰色為從機發(fā)送數(shù)據(jù)。
- 主機發(fā)送開始信號S;
- 主機發(fā)送地址數(shù)據(jù)ADDR;
- 主機發(fā)送讀信號1;
- 從機響應主機讀信號ACK;
- 從機發(fā)送數(shù)據(jù)信息DATA;
- 主機響應從機發(fā)送數(shù)據(jù)ACK;
- 循環(huán)5 6步驟可完成主機向從機連續(xù)讀數(shù)據(jù)過程;
- 主機發(fā)送結(jié)束信號P.
2.1.3 讀寫同時操作數(shù)據(jù)幀格式
主機先向從機寫數(shù)據(jù)后從從機讀數(shù)據(jù)的數(shù)據(jù)幀格式如下:
白色為主機發(fā)送數(shù)據(jù),灰色為從機發(fā)送數(shù)據(jù)。
主機可以在完成寫操作后不發(fā)送結(jié)束信號P,直接進行讀操作。該過程主機不可變,而從機可以通過發(fā)送不同地址選擇不同的從機。
2.2 IIC寫時序
IIC協(xié)議寫時序可分為單字節(jié)寫時序和連續(xù)寫時序:
2.2.1 單字節(jié)寫時序
單字節(jié)地址寫時序過程:
- 主機發(fā)送開始信號S;
- 主機發(fā)送控制字節(jié)CONTROL BYTE(7bits設備地址dev addr和1bit讀寫信號),最低位為0表示主機向從機寫數(shù)據(jù);
- 從機響應主機控制字節(jié)ACK;
- 主機發(fā)送單字節(jié)寄存器地址信息WORD ADDRESS;
- 從機響應主機發(fā)送寄存器地址ACK;
- 主機發(fā)送單字節(jié)數(shù)據(jù)信息DATA;
- 從機響應主機發(fā)送數(shù)據(jù)信息ACK;
- 主機發(fā)送結(jié)束信號P.
雙字節(jié)地址寫時序過程:
- 主機發(fā)送開始信號S;
- 主機發(fā)送控制字節(jié)CONTROL BYTE(7bits設備地址dev addr和1bit讀寫信號),最低位為0表示主機向從機寫數(shù)據(jù);
- 從機響應主機控制字節(jié)ACK;
- 主機發(fā)送寄存器地址信息高字節(jié)ADDRESS HIGH BYTE;
- 從機響應主機發(fā)送寄存器地址高字節(jié)ACK;
- 主機發(fā)送寄存器地址信息低字節(jié)ADDRESS LOW BYTE;
- 從機響應主機發(fā)送寄存器地址低字節(jié)ACK;
- 主機發(fā)送單字節(jié)數(shù)據(jù)信息DATA;
- 從機響應主機發(fā)送數(shù)據(jù)信息ACK;
- 主機發(fā)送結(jié)束信號P.
2.2.2 連續(xù)寫時序
單字節(jié)地址寫時序過程:
- 主機發(fā)送開始信號S;
- 主機發(fā)送控制字節(jié)CONTROL BYTE(7bits設備地址dev addr和1bit讀寫信號),最低位為0表示主機向從機寫數(shù)據(jù);
- 從機響應主機控制字節(jié)ACK;
- 主機發(fā)送單字節(jié)寄存器地址信息WORD ADDRESS;
- 從機響應主機發(fā)送寄存器地址ACK;
- 主機發(fā)送單字節(jié)數(shù)據(jù)信息DATA;
- 從機響應主機發(fā)送數(shù)據(jù)信息ACK;
- 循環(huán)6 7步驟可以連續(xù)向從機寫數(shù)據(jù)DATA(D+n);
- 主機發(fā)送結(jié)束信號P.
雙字節(jié)地址寫時序過程:
- 主機發(fā)送開始信號S;
- 主機發(fā)送控制字節(jié)CONTROL BYTE(7bits設備地址dev addr和1bit讀寫信號),最低位為0表示主機向從機寫數(shù)據(jù);
- 從機響應主機控制字節(jié)ACK;
- 主機發(fā)送寄存器地址信息高字節(jié)ADDRESS HIGH BYTE;
- 從機響應主機發(fā)送寄存器地址高字節(jié)ACK;
- 主機發(fā)送寄存器地址信息低字節(jié)ADDRESS LOW BYTE;
- 從機響應主機發(fā)送寄存器地址低字節(jié)ACK;
- 主機發(fā)送單字節(jié)數(shù)據(jù)信息DATA;
- 從機響應主機發(fā)送數(shù)據(jù)信息ACK;
- 循環(huán)8 9步驟可以連續(xù)向從機寫數(shù)據(jù)DATA(D+n);
- 主機發(fā)送結(jié)束信號P.
2.3 IIC讀時序
IIC協(xié)議讀時序可分為單字節(jié)讀時序和連續(xù)讀時序:
2.3.1 單字節(jié)讀時序
單字節(jié)地址讀時序過程:
- 主機發(fā)送開始信號S;
- 主機發(fā)送控制字節(jié)CONTROL BYTE(7bits設備地址dev addr和1bit讀寫信號),最低位為0表示主機向從機寫數(shù)據(jù);
- 從機響應主機控制字節(jié)ACK;
- 主機發(fā)送單字節(jié)寄存器地址信息WORD ADDRESS;
- 從機響應主機發(fā)送寄存器地址ACK;
- 主機發(fā)送開始信號S;
- 主機發(fā)送控制字節(jié)CONTROL BYTE(7bits設備地址dev addr和1bit讀寫信號),最低位為1表示主機從從機讀數(shù)據(jù);
- 從機響應主機控制字節(jié)ACK;
- 從機發(fā)送單字節(jié)數(shù)據(jù)信息DATA;
- 主機響應從機發(fā)送數(shù)據(jù)信息NACK(非應答位: 接收器是主機時,在接收到最后一個字節(jié)后發(fā)送NACK已通知被控發(fā)送從機結(jié)束數(shù)據(jù)發(fā)送,并釋放SDA數(shù)據(jù)線以便主機發(fā)送停止信號P);
- 主機發(fā)送結(jié)束信號P.
雙字節(jié)地址讀時序過程:
- 主機發(fā)送開始信號S;
- 主機發(fā)送控制字節(jié)CONTROL BYTE(7bits設備地址dev addr和1bit讀寫信號),最低位為0表示主機向從機寫數(shù)據(jù);
- 從機響應主機控制字節(jié)ACK;
- 主機發(fā)送寄存器地址信息高字節(jié)ADDRESS HIGH BYTE;
- 從機響應主機發(fā)送寄存器地址高字節(jié)ACK;
- 主機發(fā)送寄存器地址信息低字節(jié)ADDRESS LOW BYTE;
- 從機響應主機發(fā)送寄存器地址低字節(jié)ACK;
- 主機發(fā)送開始信號S;
- 主機發(fā)送控制字節(jié)CONTROL BYTE(7bits設備地址dev addr和1bit讀寫信號),最低位為1表示主機從從機讀數(shù)據(jù);
- 從機響應主機控制字節(jié)ACK;
- 從機發(fā)送單字節(jié)數(shù)據(jù)信息DATA;
- 主機響應從機發(fā)送數(shù)據(jù)信息NACK(非應答位: 接收器是主機時,在接收到最后一個字節(jié)后發(fā)送NACK已通知被控發(fā)送從機結(jié)束數(shù)據(jù)發(fā)送,并釋放SDA數(shù)據(jù)線以便主機發(fā)送停止信號P);
- 主機發(fā)送結(jié)束信號P.
2.3.2 連續(xù)讀時序
單字節(jié)地址讀時序過程:
- 主機發(fā)送開始信號S;
- 主機發(fā)送控制字節(jié)CONTROL BYTE(7bits設備地址dev addr和1bit讀寫信號),最低位為0表示主機向從機寫數(shù)據(jù);
- 從機響應主機控制字節(jié)ACK;
- 主機發(fā)送單字節(jié)寄存器地址信息WORD ADDRESS;
- 從機響應主機發(fā)送寄存器地址ACK;
- 主機發(fā)送開始信號S;
- 主機發(fā)送控制字節(jié)CONTROL BYTE(7bits設備地址dev addr和1bit讀寫信號),最低位為1表示主機從從機讀數(shù)據(jù);
- 從機響應主機控制字節(jié)ACK;
- 從機發(fā)送單字節(jié)數(shù)據(jù)信息DATA;
- 主機響應從機發(fā)送數(shù)據(jù)信息ACK;
- 循環(huán)9 10步驟可完成主機向從機連續(xù)讀數(shù)據(jù)過程,讀取最后一個字節(jié)數(shù)據(jù)時主機應響應NACK(非應答位: 接收器是主機時,在接收到最后一個字節(jié)后發(fā)送NACK已通知被控發(fā)送從機結(jié)束數(shù)據(jù)發(fā)送,并釋放SDA數(shù)據(jù)線以便主機發(fā)送停止信號P);
- 主機發(fā)送結(jié)束信號P.
雙字節(jié)地址讀時序過程:
- 主機發(fā)送開始信號S;
- 主機發(fā)送控制字節(jié)CONTROL BYTE(7bits設備地址dev addr和1bit讀寫信號),最低位為0表示主機向從機寫數(shù)據(jù);
- 從機響應主機控制字節(jié)ACK;
- 主機發(fā)送寄存器地址信息高字節(jié)ADDRESS HIGH BYTE;
- 從機響應主機發(fā)送寄存器地址高字節(jié)ACK;
- 主機發(fā)送寄存器地址信息低字節(jié)ADDRESS LOW BYTE;
- 從機響應主機發(fā)送寄存器地址低字節(jié)ACK;
- 主機發(fā)送開始信號S;
- 主機發(fā)送控制字節(jié)CONTROL BYTE(7bits設備地址dev addr和1bit讀寫信號),最低位為1表示主機從從機讀數(shù)據(jù);
- 從機響應主機控制字節(jié)ACK;
- 從機發(fā)送單字節(jié)數(shù)據(jù)信息DATA;
- 主機響應從機發(fā)送數(shù)據(jù)信息ACK;
- 循環(huán)11 12步驟可完成主機向從機連續(xù)讀數(shù)據(jù)過程,讀取最后一個字節(jié)數(shù)據(jù)時主機應響應NACK(非應答位: 接收器是主機時,在接收到最后一個字節(jié)后發(fā)送NACK已通知被控發(fā)送從機結(jié)束數(shù)據(jù)發(fā)送,并釋放SDA數(shù)據(jù)線以便主機發(fā)送停止信號P);
- 主機發(fā)送結(jié)束信號P.
03
IIC代碼實現(xiàn)
3.1 IIC目標實現(xiàn)功能
設計一個IIC模塊,具體要求如下:
設計一個IIC協(xié)議提供給主設備,通過查找表實現(xiàn)對從設備寄存器進行配置。按查找表順序lut_index依次對設備地址為lut_dev_addr的從設備寄存器進行配置,為lut_reg_addr配置寄存器數(shù)據(jù)lut_reg_data,同時將傳輸異常和傳輸結(jié)束信號引出以對傳輸過程進行監(jiān)控。模塊的定義如下:
module i2c(
input rst, //復位信號
input clk, //時鐘信號
input[15:0] clk_div_cnt, //時鐘計數(shù)器
input i2c_addr_2byte, //雙字節(jié)地址
output reg[9:0] lut_index, //查找表順序號
input[7:0] lut_dev_addr, //從設備地址
input[15:0] lut_reg_addr, //寄存器地址
input[7:0] lut_reg_data, //寄存器數(shù)據(jù)
output reg error, //傳輸異常信號
output done, //傳輸結(jié)束信號
inout i2c_scl, //IIC時鐘信號
inout i2c_sda //IIC數(shù)據(jù)信號
);
3.2 Verilog代碼
1. 頂層模塊 (i2c):
module i2c(
input rst,
input clk,
input[15:0] clk_div_cnt,
input i2c_addr_2byte,
output reg[9:0] lut_index,
input[7:0] lut_dev_addr,
input[15:0] lut_reg_addr,
input[7:0] lut_reg_data,
output reg error,
output done,
inout i2c_scl,
inout i2c_sda
);
wire scl_pad_i;
wire scl_pad_o;
wire scl_padoen_o;
wire sda_pad_i;
wire sda_pad_o;
wire sda_padoen_o;
assign sda_pad_i = i2c_sda;
assign i2c_sda = ~sda_padoen_o ? sda_pad_o : 1'bz;
assign scl_pad_i = i2c_scl;
assign i2c_scl = ~scl_padoen_o ? scl_pad_o : 1'bz;
reg i2c_read_req;
wire i2c_read_req_ack;
reg i2c_write_req;
wire i2c_write_req_ack;
wire[7:0] i2c_slave_dev_addr;
wire[15:0] i2c_slave_reg_addr;
wire[7:0] i2c_write_data;
wire[7:0] i2c_read_data;
wire err;
reg[2:0] state;
localparam S_IDLE = 0;
localparam S_WR_I2C_CHECK = 1;
localparam S_WR_I2C = 2;
localparam S_WR_I2C_DONE = 3;
assign done = (state == S_WR_I2C_DONE);
assign i2c_slave_dev_addr = lut_dev_addr;
assign i2c_slave_reg_addr = lut_reg_addr;
assign i2c_write_data = lut_reg_data;
//cascatrix carson
always@(posedge clk or posedge rst)
begin
if(rst)
begin
state <= S_IDLE;
error <= 1'b0;
lut_index <= 8'd0;
end
else
case(state)
S_IDLE:
begin
state <= S_WR_I2C_CHECK;
error <= 1'b0;
lut_index <= 8'd0;
end
S_WR_I2C_CHECK:
begin
if(i2c_slave_dev_addr != 8'hff)
begin
i2c_write_req <= 1'b1;
state <= S_WR_I2C;
end
else
begin
state <= S_WR_I2C_DONE;
end
end
S_WR_I2C:
begin
if(i2c_write_req_ack)
begin
error <= err ? 1'b1 : error;
lut_index <= lut_index + 8'd1;
i2c_write_req <= 1'b0;
state <= S_WR_I2C_CHECK;
end
end
S_WR_I2C_DONE:
begin
state <= S_WR_I2C_DONE;
end
default:
state <= S_IDLE;
endcase
end
i2c_ctrl i2c_ctrl
(
.rst(rst),
.clk(clk),
.clk_div_cnt(clk_div_cnt),
// I2C signals
// i2c clock line
.scl_pad_i(scl_pad_i), // SCL-line input
.scl_pad_o(scl_pad_o), // SCL-line output (always 1'b0)
.scl_padoen_o(scl_padoen_o), // SCL-line output enable (active low)
// i2c data line
.sda_pad_i(sda_pad_i), // SDA-line input
.sda_pad_o(sda_pad_o), // SDA-line output (always 1'b0)
.sda_padoen_o(sda_padoen_o), // SDA-line output enable (active low)
.i2c_read_req(i2c_read_req),
.i2c_addr_2byte(i2c_addr_2byte),
.i2c_read_req_ack(i2c_read_req_ack),
.i2c_write_req(i2c_write_req),
.i2c_write_req_ack(i2c_write_req_ack),
.i2c_slave_dev_addr(i2c_slave_dev_addr),
.i2c_slave_reg_addr(i2c_slave_reg_addr),
.i2c_write_data(i2c_write_data),
.i2c_read_data(i2c_read_data),
.error(err)
);
endmodule
-
IIC
+關(guān)注
關(guān)注
11文章
304瀏覽量
38984 -
通信總線
+關(guān)注
關(guān)注
0文章
46瀏覽量
9957 -
SDA
+關(guān)注
關(guān)注
0文章
124瀏覽量
28615
發(fā)布評論請先 登錄
相關(guān)推薦
一文詳解IIC總線

一文詳解IIC總線

常用的串行總線協(xié)議有哪些
IIC總線協(xié)議的相關(guān)資料下載
IIC協(xié)議的相關(guān)資料推薦
FPGA基礎知識之IIC協(xié)議讀寫解析

IIC總線協(xié)議及應用

評論