01
IIC基礎(chǔ)知識
集成電路總線 (Inter-Intergrated Circuit),通常稱作IICBUS,簡稱為IIC,是一種采用多主從結(jié)構(gòu)的串行通信總線。
IIC由PHILIPS公司于1980年推出,利用該總線可實現(xiàn)多主機(jī)系統(tǒng)所需的裁決和高低速設(shè)備同步等功能。
IIC串行總線一般有兩根信號線,分別是時鐘線SCL和數(shù)據(jù)線SDA,所有IIC總線各設(shè)備的串行數(shù)據(jù)SDA接到總線SDA上,時鐘線SLC接到總線SCL上。
雙向串行數(shù)據(jù)SDA:輸出電路用于向總線發(fā)送數(shù)據(jù),輸入電路用于接收總線上的數(shù)據(jù);
雙向時鐘數(shù)據(jù)SCL:輸出電路用于向總線發(fā)送時鐘信號,輸入電路用于檢測總線時鐘電平以決定下次時鐘脈沖電平時間。
各設(shè)備與總線相連的輸出端采用高阻態(tài)以避免總線信號的混亂,通常采用漏極開路輸出或集電極開路輸出。總線空閑時,各設(shè)備都是開漏輸出,通??刹捎蒙侠?a target="_blank">電阻使總線保持高電平,而任一設(shè)備輸出低電平都將拉低相應(yīng)的總線信號。
IIC總線上的設(shè)備可分為主設(shè)備和從設(shè)備兩種:主設(shè)備有權(quán)利主動發(fā)起/結(jié)束一次通信;從設(shè)備只能被動響應(yīng)。
所有連接在IIC總線上的設(shè)備都有各自唯一的地址(原地址位寬為7bits,改進(jìn)后采用10bits位寬),每個設(shè)備都可以作為主設(shè)備或從設(shè)備,但是同一時刻只能有一個主設(shè)備控制。
如果總線上有多個設(shè)備同時啟用總線,IIC通過檢測和仲裁機(jī)制解決傳輸沖突。IIC允許連接的設(shè)備傳輸速率不同,多臺設(shè)備之間時鐘信號的同步過程稱為同步化。
02
IIC傳輸協(xié)議
2.1 IIC協(xié)議模式
IIC協(xié)議為半雙工模式,同一條數(shù)據(jù)線上完成讀/寫操作,不同操作時的數(shù)據(jù)幀格式可分為寫操作、讀操作、讀寫操作。
2.1.1 寫操作數(shù)據(jù)幀格式
主機(jī)向從機(jī)寫數(shù)據(jù)的數(shù)據(jù)幀格式如下:
白色為主機(jī)發(fā)送數(shù)據(jù),灰色為從機(jī)發(fā)送數(shù)據(jù)。
- 主機(jī)發(fā)送開始信號S;
- 主機(jī)發(fā)送地址數(shù)據(jù)ADDR;
- 主機(jī)發(fā)送寫信號0;
- 從機(jī)響應(yīng)主機(jī)寫信號ACK;
- 主機(jī)發(fā)送數(shù)據(jù)信息DATA;
- 從機(jī)響應(yīng)主機(jī)發(fā)送數(shù)據(jù)ACK;
- 循環(huán)5 6步驟可完成主機(jī)向從機(jī)連續(xù)寫數(shù)據(jù)過程;
- 主機(jī)發(fā)送結(jié)束信號P.
2.1.2 讀操作數(shù)據(jù)幀格式
主機(jī)從從機(jī)讀數(shù)據(jù)的數(shù)據(jù)幀格式如下:
白色為主機(jī)發(fā)送數(shù)據(jù),灰色為從機(jī)發(fā)送數(shù)據(jù)。
- 主機(jī)發(fā)送開始信號S;
- 主機(jī)發(fā)送地址數(shù)據(jù)ADDR;
- 主機(jī)發(fā)送讀信號1;
- 從機(jī)響應(yīng)主機(jī)讀信號ACK;
- 從機(jī)發(fā)送數(shù)據(jù)信息DATA;
- 主機(jī)響應(yīng)從機(jī)發(fā)送數(shù)據(jù)ACK;
- 循環(huán)5 6步驟可完成主機(jī)向從機(jī)連續(xù)讀數(shù)據(jù)過程;
- 主機(jī)發(fā)送結(jié)束信號P.
2.1.3 讀寫同時操作數(shù)據(jù)幀格式
主機(jī)先向從機(jī)寫數(shù)據(jù)后從從機(jī)讀數(shù)據(jù)的數(shù)據(jù)幀格式如下:
白色為主機(jī)發(fā)送數(shù)據(jù),灰色為從機(jī)發(fā)送數(shù)據(jù)。
主機(jī)可以在完成寫操作后不發(fā)送結(jié)束信號P,直接進(jìn)行讀操作。該過程主機(jī)不可變,而從機(jī)可以通過發(fā)送不同地址選擇不同的從機(jī)。
2.2 IIC寫時序
IIC協(xié)議寫時序可分為單字節(jié)寫時序和連續(xù)寫時序:
2.2.1 單字節(jié)寫時序
單字節(jié)地址寫時序過程:
- 主機(jī)發(fā)送開始信號S;
- 主機(jī)發(fā)送控制字節(jié)CONTROL BYTE(7bits設(shè)備地址dev addr和1bit讀寫信號),最低位為0表示主機(jī)向從機(jī)寫數(shù)據(jù);
- 從機(jī)響應(yīng)主機(jī)控制字節(jié)ACK;
- 主機(jī)發(fā)送單字節(jié)寄存器地址信息WORD ADDRESS;
- 從機(jī)響應(yīng)主機(jī)發(fā)送寄存器地址ACK;
- 主機(jī)發(fā)送單字節(jié)數(shù)據(jù)信息DATA;
- 從機(jī)響應(yīng)主機(jī)發(fā)送數(shù)據(jù)信息ACK;
- 主機(jī)發(fā)送結(jié)束信號P.
雙字節(jié)地址寫時序過程:
- 主機(jī)發(fā)送開始信號S;
- 主機(jī)發(fā)送控制字節(jié)CONTROL BYTE(7bits設(shè)備地址dev addr和1bit讀寫信號),最低位為0表示主機(jī)向從機(jī)寫數(shù)據(jù);
- 從機(jī)響應(yīng)主機(jī)控制字節(jié)ACK;
- 主機(jī)發(fā)送寄存器地址信息高字節(jié)ADDRESS HIGH BYTE;
- 從機(jī)響應(yīng)主機(jī)發(fā)送寄存器地址高字節(jié)ACK;
- 主機(jī)發(fā)送寄存器地址信息低字節(jié)ADDRESS LOW BYTE;
- 從機(jī)響應(yīng)主機(jī)發(fā)送寄存器地址低字節(jié)ACK;
- 主機(jī)發(fā)送單字節(jié)數(shù)據(jù)信息DATA;
- 從機(jī)響應(yīng)主機(jī)發(fā)送數(shù)據(jù)信息ACK;
- 主機(jī)發(fā)送結(jié)束信號P.
2.2.2 連續(xù)寫時序
單字節(jié)地址寫時序過程:
- 主機(jī)發(fā)送開始信號S;
- 主機(jī)發(fā)送控制字節(jié)CONTROL BYTE(7bits設(shè)備地址dev addr和1bit讀寫信號),最低位為0表示主機(jī)向從機(jī)寫數(shù)據(jù);
- 從機(jī)響應(yīng)主機(jī)控制字節(jié)ACK;
- 主機(jī)發(fā)送單字節(jié)寄存器地址信息WORD ADDRESS;
- 從機(jī)響應(yīng)主機(jī)發(fā)送寄存器地址ACK;
- 主機(jī)發(fā)送單字節(jié)數(shù)據(jù)信息DATA;
- 從機(jī)響應(yīng)主機(jī)發(fā)送數(shù)據(jù)信息ACK;
- 循環(huán)6 7步驟可以連續(xù)向從機(jī)寫數(shù)據(jù)DATA(D+n);
- 主機(jī)發(fā)送結(jié)束信號P.
雙字節(jié)地址寫時序過程:
- 主機(jī)發(fā)送開始信號S;
- 主機(jī)發(fā)送控制字節(jié)CONTROL BYTE(7bits設(shè)備地址dev addr和1bit讀寫信號),最低位為0表示主機(jī)向從機(jī)寫數(shù)據(jù);
- 從機(jī)響應(yīng)主機(jī)控制字節(jié)ACK;
- 主機(jī)發(fā)送寄存器地址信息高字節(jié)ADDRESS HIGH BYTE;
- 從機(jī)響應(yīng)主機(jī)發(fā)送寄存器地址高字節(jié)ACK;
- 主機(jī)發(fā)送寄存器地址信息低字節(jié)ADDRESS LOW BYTE;
- 從機(jī)響應(yīng)主機(jī)發(fā)送寄存器地址低字節(jié)ACK;
- 主機(jī)發(fā)送單字節(jié)數(shù)據(jù)信息DATA;
- 從機(jī)響應(yīng)主機(jī)發(fā)送數(shù)據(jù)信息ACK;
- 循環(huán)8 9步驟可以連續(xù)向從機(jī)寫數(shù)據(jù)DATA(D+n);
- 主機(jī)發(fā)送結(jié)束信號P.
2.3 IIC讀時序
IIC協(xié)議讀時序可分為單字節(jié)讀時序和連續(xù)讀時序:
2.3.1 單字節(jié)讀時序
單字節(jié)地址讀時序過程:
- 主機(jī)發(fā)送開始信號S;
- 主機(jī)發(fā)送控制字節(jié)CONTROL BYTE(7bits設(shè)備地址dev addr和1bit讀寫信號),最低位為0表示主機(jī)向從機(jī)寫數(shù)據(jù);
- 從機(jī)響應(yīng)主機(jī)控制字節(jié)ACK;
- 主機(jī)發(fā)送單字節(jié)寄存器地址信息WORD ADDRESS;
- 從機(jī)響應(yīng)主機(jī)發(fā)送寄存器地址ACK;
- 主機(jī)發(fā)送開始信號S;
- 主機(jī)發(fā)送控制字節(jié)CONTROL BYTE(7bits設(shè)備地址dev addr和1bit讀寫信號),最低位為1表示主機(jī)從從機(jī)讀數(shù)據(jù);
- 從機(jī)響應(yīng)主機(jī)控制字節(jié)ACK;
- 從機(jī)發(fā)送單字節(jié)數(shù)據(jù)信息DATA;
- 主機(jī)響應(yīng)從機(jī)發(fā)送數(shù)據(jù)信息NACK(非應(yīng)答位: 接收器是主機(jī)時,在接收到最后一個字節(jié)后發(fā)送NACK已通知被控發(fā)送從機(jī)結(jié)束數(shù)據(jù)發(fā)送,并釋放SDA數(shù)據(jù)線以便主機(jī)發(fā)送停止信號P);
- 主機(jī)發(fā)送結(jié)束信號P.
雙字節(jié)地址讀時序過程:
- 主機(jī)發(fā)送開始信號S;
- 主機(jī)發(fā)送控制字節(jié)CONTROL BYTE(7bits設(shè)備地址dev addr和1bit讀寫信號),最低位為0表示主機(jī)向從機(jī)寫數(shù)據(jù);
- 從機(jī)響應(yīng)主機(jī)控制字節(jié)ACK;
- 主機(jī)發(fā)送寄存器地址信息高字節(jié)ADDRESS HIGH BYTE;
- 從機(jī)響應(yīng)主機(jī)發(fā)送寄存器地址高字節(jié)ACK;
- 主機(jī)發(fā)送寄存器地址信息低字節(jié)ADDRESS LOW BYTE;
- 從機(jī)響應(yīng)主機(jī)發(fā)送寄存器地址低字節(jié)ACK;
- 主機(jī)發(fā)送開始信號S;
- 主機(jī)發(fā)送控制字節(jié)CONTROL BYTE(7bits設(shè)備地址dev addr和1bit讀寫信號),最低位為1表示主機(jī)從從機(jī)讀數(shù)據(jù);
- 從機(jī)響應(yīng)主機(jī)控制字節(jié)ACK;
- 從機(jī)發(fā)送單字節(jié)數(shù)據(jù)信息DATA;
- 主機(jī)響應(yīng)從機(jī)發(fā)送數(shù)據(jù)信息NACK(非應(yīng)答位: 接收器是主機(jī)時,在接收到最后一個字節(jié)后發(fā)送NACK已通知被控發(fā)送從機(jī)結(jié)束數(shù)據(jù)發(fā)送,并釋放SDA數(shù)據(jù)線以便主機(jī)發(fā)送停止信號P);
- 主機(jī)發(fā)送結(jié)束信號P.
2.3.2 連續(xù)讀時序
單字節(jié)地址讀時序過程:
- 主機(jī)發(fā)送開始信號S;
- 主機(jī)發(fā)送控制字節(jié)CONTROL BYTE(7bits設(shè)備地址dev addr和1bit讀寫信號),最低位為0表示主機(jī)向從機(jī)寫數(shù)據(jù);
- 從機(jī)響應(yīng)主機(jī)控制字節(jié)ACK;
- 主機(jī)發(fā)送單字節(jié)寄存器地址信息WORD ADDRESS;
- 從機(jī)響應(yīng)主機(jī)發(fā)送寄存器地址ACK;
- 主機(jī)發(fā)送開始信號S;
- 主機(jī)發(fā)送控制字節(jié)CONTROL BYTE(7bits設(shè)備地址dev addr和1bit讀寫信號),最低位為1表示主機(jī)從從機(jī)讀數(shù)據(jù);
- 從機(jī)響應(yīng)主機(jī)控制字節(jié)ACK;
- 從機(jī)發(fā)送單字節(jié)數(shù)據(jù)信息DATA;
- 主機(jī)響應(yīng)從機(jī)發(fā)送數(shù)據(jù)信息ACK;
- 循環(huán)9 10步驟可完成主機(jī)向從機(jī)連續(xù)讀數(shù)據(jù)過程,讀取最后一個字節(jié)數(shù)據(jù)時主機(jī)應(yīng)響應(yīng)NACK(非應(yīng)答位: 接收器是主機(jī)時,在接收到最后一個字節(jié)后發(fā)送NACK已通知被控發(fā)送從機(jī)結(jié)束數(shù)據(jù)發(fā)送,并釋放SDA數(shù)據(jù)線以便主機(jī)發(fā)送停止信號P);
- 主機(jī)發(fā)送結(jié)束信號P.
雙字節(jié)地址讀時序過程:
- 主機(jī)發(fā)送開始信號S;
- 主機(jī)發(fā)送控制字節(jié)CONTROL BYTE(7bits設(shè)備地址dev addr和1bit讀寫信號),最低位為0表示主機(jī)向從機(jī)寫數(shù)據(jù);
- 從機(jī)響應(yīng)主機(jī)控制字節(jié)ACK;
- 主機(jī)發(fā)送寄存器地址信息高字節(jié)ADDRESS HIGH BYTE;
- 從機(jī)響應(yīng)主機(jī)發(fā)送寄存器地址高字節(jié)ACK;
- 主機(jī)發(fā)送寄存器地址信息低字節(jié)ADDRESS LOW BYTE;
- 從機(jī)響應(yīng)主機(jī)發(fā)送寄存器地址低字節(jié)ACK;
- 主機(jī)發(fā)送開始信號S;
- 主機(jī)發(fā)送控制字節(jié)CONTROL BYTE(7bits設(shè)備地址dev addr和1bit讀寫信號),最低位為1表示主機(jī)從從機(jī)讀數(shù)據(jù);
- 從機(jī)響應(yīng)主機(jī)控制字節(jié)ACK;
- 從機(jī)發(fā)送單字節(jié)數(shù)據(jù)信息DATA;
- 主機(jī)響應(yīng)從機(jī)發(fā)送數(shù)據(jù)信息ACK;
- 循環(huán)11 12步驟可完成主機(jī)向從機(jī)連續(xù)讀數(shù)據(jù)過程,讀取最后一個字節(jié)數(shù)據(jù)時主機(jī)應(yīng)響應(yīng)NACK(非應(yīng)答位: 接收器是主機(jī)時,在接收到最后一個字節(jié)后發(fā)送NACK已通知被控發(fā)送從機(jī)結(jié)束數(shù)據(jù)發(fā)送,并釋放SDA數(shù)據(jù)線以便主機(jī)發(fā)送停止信號P);
- 主機(jī)發(fā)送結(jié)束信號P.
03
IIC代碼實現(xiàn)
3.1 IIC目標(biāo)實現(xiàn)功能
設(shè)計一個IIC模塊,具體要求如下:
設(shè)計一個IIC協(xié)議提供給主設(shè)備,通過查找表實現(xiàn)對從設(shè)備寄存器進(jìn)行配置。按查找表順序lut_index依次對設(shè)備地址為lut_dev_addr的從設(shè)備寄存器進(jìn)行配置,為lut_reg_addr配置寄存器數(shù)據(jù)lut_reg_data,同時將傳輸異常和傳輸結(jié)束信號引出以對傳輸過程進(jìn)行監(jiān)控。模塊的定義如下:
module i2c(
input rst, //復(fù)位信號
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, //從設(shè)備地址
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文章
302瀏覽量
38539 -
通信總線
+關(guān)注
關(guān)注
0文章
45瀏覽量
9892 -
SDA
+關(guān)注
關(guān)注
0文章
124瀏覽量
28281
發(fā)布評論請先 登錄
相關(guān)推薦
一文詳解IIC總線
![<b class='flag-5'>一</b><b class='flag-5'>文</b>詳解<b class='flag-5'>IIC</b><b class='flag-5'>總線</b>](https://file1.elecfans.com//web2/M00/89/4C/wKgaomSAM-aARtvuAAJwA-mo2z0756.jpg)
一文詳解IIC總線
![<b class='flag-5'>一</b><b class='flag-5'>文</b>詳解<b class='flag-5'>IIC</b><b class='flag-5'>總線</b>](https://file1.elecfans.com/web2/M00/A2/98/wKgZomT_17OAfMeuAAC3OX_IP-s899.png)
常用的串行總線協(xié)議有哪些
IIC總線協(xié)議的相關(guān)資料下載
IIC協(xié)議的相關(guān)資料推薦
FPGA基礎(chǔ)知識之IIC協(xié)議讀寫解析
![FPGA基礎(chǔ)知識<b class='flag-5'>之</b><b class='flag-5'>IIC</b><b class='flag-5'>協(xié)議</b>讀寫解析](https://file.elecfans.com/web1/M00/50/23/pIYBAFrtI2iADxYeAAAf8ue__p4874.png)
IIC總線協(xié)議及應(yīng)用
![<b class='flag-5'>IIC</b><b class='flag-5'>總線</b><b class='flag-5'>協(xié)議</b>及應(yīng)用](https://file.elecfans.com/web1/M00/D9/4E/pIYBAF_1ac2Ac0EEAABDkS1IP1s689.png)
評論