0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

一文带你迅速了解常用串行总线之IIC协议1

jf_78858299 来源:Cascatrix 作者:Cascatrix 2023-01-21 17:19 次阅读

01

IIC基础知识

集成电路总线 (Inter-Intergrated Circuit),通常称作IICBUS,简称为IIC,是一种采用多主从结构的串行通信总线。

IIC由PHILIPS公司于1980年推出,利用该总线可实现多主机系统所需的裁决和高低速设备同步等功能。

IIC串行总线一般有两根信号线,分别是时钟线SCL和数据线SDA,所有IIC总线各设备的串行数据SDA接到总线SDA上,时钟线SLC接到总线SCL上。

双向串行数据SDA:输出电路用于向总线发送数据,输入电路用于接收总线上的数据;

双向时钟数据SCL:输出电路用于向总线发送时钟信号,输入电路用于检测总线时钟电平以决定下次时钟脉冲电平时间。

各设备与总线相连的输出端采用高阻态以避免总线信号的混乱,通常采用漏极开路输出或集电极开路输出。总线空闲时,各设备都是开漏输出,通常可采用上拉电阻使总线保持高电平,而任一设备输出低电平都将拉低相应的总线信号。

图片

IIC总线上的设备可分为主设备和从设备两种:主设备有权利主动发起/结束一次通信;从设备只能被动响应。

所有连接在IIC总线上的设备都有各自唯一的地址(原地址位宽为7bits,改进后采用10bits位宽),每个设备都可以作为主设备或从设备,但是同一时刻只能有一个主设备控制。

如果总线上有多个设备同时启用总线,IIC通过检测和仲裁机制解决传输冲突。IIC允许连接的设备传输速率不同,多台设备之间时钟信号的同步过程称为同步化。

02

IIC传输协议

2.1 IIC协议模式

IIC协议为半双工模式,同一条数据线上完成读/写操作,不同操作时的数据帧格式可分为写操作、读操作、读写操作。

2.1.1 写操作数据帧格式

主机向从机写数据的数据帧格式如下:

图片

白色为主机发送数据,灰色为从机发送数据。

  1. 主机发送开始信号S;
  2. 主机发送地址数据ADDR;
  3. 主机发送写信号0;
  4. 从机响应主机写信号ACK;
  5. 主机发送数据信息DATA;
  6. 从机响应主机发送数据ACK;
  7. 循环5 6步骤可完成主机向从机连续写数据过程;
  8. 主机发送结束信号P.

2.1.2 读操作数据帧格式

主机从从机读数据的数据帧格式如下:

图片

白色为主机发送数据,灰色为从机发送数据。

  1. 主机发送开始信号S;
  2. 主机发送地址数据ADDR;
  3. 主机发送读信号1;
  4. 从机响应主机读信号ACK;
  5. 从机发送数据信息DATA;
  6. 主机响应从机发送数据ACK;
  7. 循环5 6步骤可完成主机向从机连续读数据过程;
  8. 主机发送结束信号P.

2.1.3 读写同时操作数据帧格式

主机先向从机写数据后从从机读数据的数据帧格式如下:

图片

白色为主机发送数据,灰色为从机发送数据。

主机可以在完成写操作后不发送结束信号P,直接进行读操作。该过程主机不可变,而从机可以通过发送不同地址选择不同的从机。

2.2 IIC写时序

IIC协议写时序可分为单字节写时序和连续写时序:

2.2.1 单字节写时序

单字节地址写时序过程:

图片

  1. 主机发送开始信号S;
  2. 主机发送控制字节CONTROL BYTE(7bits设备地址dev addr和1bit读写信号),最低位为0表示主机向从机写数据;
  3. 从机响应主机控制字节ACK;
  4. 主机发送单字节寄存器地址信息WORD ADDRESS;
  5. 从机响应主机发送寄存器地址ACK;
  6. 主机发送单字节数据信息DATA;
  7. 从机响应主机发送数据信息ACK;
  8. 主机发送结束信号P.

双字节地址写时序过程:

图片

  1. 主机发送开始信号S;
  2. 主机发送控制字节CONTROL BYTE(7bits设备地址dev addr和1bit读写信号),最低位为0表示主机向从机写数据;
  3. 从机响应主机控制字节ACK;
  4. 主机发送寄存器地址信息高字节ADDRESS HIGH BYTE;
  5. 从机响应主机发送寄存器地址高字节ACK;
  6. 主机发送寄存器地址信息低字节ADDRESS LOW BYTE;
  7. 从机响应主机发送寄存器地址低字节ACK;
  8. 主机发送单字节数据信息DATA;
  9. 从机响应主机发送数据信息ACK;
  10. 主机发送结束信号P.

2.2.2 连续写时序

单字节地址写时序过程:

图片

  1. 主机发送开始信号S;
  2. 主机发送控制字节CONTROL BYTE(7bits设备地址dev addr和1bit读写信号),最低位为0表示主机向从机写数据;
  3. 从机响应主机控制字节ACK;
  4. 主机发送单字节寄存器地址信息WORD ADDRESS;
  5. 从机响应主机发送寄存器地址ACK;
  6. 主机发送单字节数据信息DATA;
  7. 从机响应主机发送数据信息ACK;
  8. 循环6 7步骤可以连续向从机写数据DATA(D+n);
  9. 主机发送结束信号P.

双字节地址写时序过程:

图片

  1. 主机发送开始信号S;
  2. 主机发送控制字节CONTROL BYTE(7bits设备地址dev addr和1bit读写信号),最低位为0表示主机向从机写数据;
  3. 从机响应主机控制字节ACK;
  4. 主机发送寄存器地址信息高字节ADDRESS HIGH BYTE;
  5. 从机响应主机发送寄存器地址高字节ACK;
  6. 主机发送寄存器地址信息低字节ADDRESS LOW BYTE;
  7. 从机响应主机发送寄存器地址低字节ACK;
  8. 主机发送单字节数据信息DATA;
  9. 从机响应主机发送数据信息ACK;
  10. 循环8 9步骤可以连续向从机写数据DATA(D+n);
  11. 主机发送结束信号P.

2.3 IIC读时序

IIC协议读时序可分为单字节读时序和连续读时序:

2.3.1 单字节读时序

单字节地址读时序过程:

图片

  1. 主机发送开始信号S;
  2. 主机发送控制字节CONTROL BYTE(7bits设备地址dev addr和1bit读写信号),最低位为0表示主机向从机写数据;
  3. 从机响应主机控制字节ACK;
  4. 主机发送单字节寄存器地址信息WORD ADDRESS;
  5. 从机响应主机发送寄存器地址ACK;
  6. 主机发送开始信号S;
  7. 主机发送控制字节CONTROL BYTE(7bits设备地址dev addr和1bit读写信号),最低位为1表示主机从从机读数据;
  8. 从机响应主机控制字节ACK;
  9. 从机发送单字节数据信息DATA;
  10. 主机响应从机发送数据信息NACK(非应答位: 接收器是主机时,在接收到最后一个字节后发送NACK已通知被控发送从机结束数据发送,并释放SDA数据线以便主机发送停止信号P);
  11. 主机发送结束信号P.

双字节地址读时序过程:

图片

  1. 主机发送开始信号S;
  2. 主机发送控制字节CONTROL BYTE(7bits设备地址dev addr和1bit读写信号),最低位为0表示主机向从机写数据;
  3. 从机响应主机控制字节ACK;
  4. 主机发送寄存器地址信息高字节ADDRESS HIGH BYTE;
  5. 从机响应主机发送寄存器地址高字节ACK;
  6. 主机发送寄存器地址信息低字节ADDRESS LOW BYTE;
  7. 从机响应主机发送寄存器地址低字节ACK;
  8. 主机发送开始信号S;
  9. 主机发送控制字节CONTROL BYTE(7bits设备地址dev addr和1bit读写信号),最低位为1表示主机从从机读数据;
  10. 从机响应主机控制字节ACK;
  11. 从机发送单字节数据信息DATA;
  12. 主机响应从机发送数据信息NACK(非应答位: 接收器是主机时,在接收到最后一个字节后发送NACK已通知被控发送从机结束数据发送,并释放SDA数据线以便主机发送停止信号P);
  13. 主机发送结束信号P.

2.3.2 连续读时序

单字节地址读时序过程:

图片

  1. 主机发送开始信号S;
  2. 主机发送控制字节CONTROL BYTE(7bits设备地址dev addr和1bit读写信号),最低位为0表示主机向从机写数据;
  3. 从机响应主机控制字节ACK;
  4. 主机发送单字节寄存器地址信息WORD ADDRESS;
  5. 从机响应主机发送寄存器地址ACK;
  6. 主机发送开始信号S;
  7. 主机发送控制字节CONTROL BYTE(7bits设备地址dev addr和1bit读写信号),最低位为1表示主机从从机读数据;
  8. 从机响应主机控制字节ACK;
  9. 从机发送单字节数据信息DATA;
  10. 主机响应从机发送数据信息ACK;
  11. 循环9 10步骤可完成主机向从机连续读数据过程,读取最后一个字节数据时主机应响应NACK(非应答位: 接收器是主机时,在接收到最后一个字节后发送NACK已通知被控发送从机结束数据发送,并释放SDA数据线以便主机发送停止信号P);
  12. 主机发送结束信号P.

双字节地址读时序过程:

图片

  1. 主机发送开始信号S;
  2. 主机发送控制字节CONTROL BYTE(7bits设备地址dev addr和1bit读写信号),最低位为0表示主机向从机写数据;
  3. 从机响应主机控制字节ACK;
  4. 主机发送寄存器地址信息高字节ADDRESS HIGH BYTE;
  5. 从机响应主机发送寄存器地址高字节ACK;
  6. 主机发送寄存器地址信息低字节ADDRESS LOW BYTE;
  7. 从机响应主机发送寄存器地址低字节ACK;
  8. 主机发送开始信号S;
  9. 主机发送控制字节CONTROL BYTE(7bits设备地址dev addr和1bit读写信号),最低位为1表示主机从从机读数据;
  10. 从机响应主机控制字节ACK;
  11. 从机发送单字节数据信息DATA;
  12. 主机响应从机发送数据信息ACK;
  13. 循环11 12步骤可完成主机向从机连续读数据过程,读取最后一个字节数据时主机应响应NACK(非应答位: 接收器是主机时,在接收到最后一个字节后发送NACK已通知被控发送从机结束数据发送,并释放SDA数据线以便主机发送停止信号P);
  14. 主机发送结束信号P.

03

IIC代码实现

3.1 IIC目标实现功能

设计一个IIC模块,具体要求如下:

设计一个IIC协议提供给主设备,通过查找表实现对从设备寄存器进行配置。按查找表顺序lut_index依次对设备地址为lut_dev_addr的从设备寄存器进行配置,为lut_reg_addr配置寄存器数据lut_reg_data,同时将传输异常和传输结束信号引出以对传输过程进行监控。模块的定义如下:

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, //IIC时钟信号

inout i2c_sda //IIC数据信号

);

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
    IIC
    +关注

    关注

    11

    文章

    285

    浏览量

    37806
  • 通信总线
    +关注

    关注

    0

    文章

    40

    浏览量

    9791
  • SDA
    SDA
    +关注

    关注

    0

    文章

    122

    浏览量

    27557
收藏 人收藏

    评论

    相关推荐

    IIC总线串行技术

    IIC总线串行技术的电子书
    发表于 02-19 16:32

    IIC总线概念01

    IIC协议种二线的串行总线协议。最新的IIC规范
    发表于 06-09 21:41

    IIC总线协议与SCCB协议的区别

    先简单介绍IIC总线协议IIC总线是philips公司推出的新
    发表于 08-07 12:43

    常用串行总线协议有哪些

    常用串行总线协议目前常用的微机与外设之间进行数据传输的
    发表于 11-03 07:14

    常用串行总线协议有哪些

    常用串行总线协议I2C总线、SPI总线、SCI总线
    发表于 11-19 06:46

    IIC总线协议的相关资料下载

    (串行数据线)和SCL(串行时钟线)及上拉电阻组成。通信原理是通过对SCL和SDA线高低电平时序的控制,来 产生I2C总线协议所需要的信号进行数据的传递。在
    发表于 11-30 08:29

    串行通信中的IIC总线工作原理是什么

    串行通信中的IIC总线工作原理51本身不带IIC总线 ,使用程序模拟IIC通信
    发表于 12-08 07:52

    IIC协议的相关资料推荐

    STM32 IIC实验讲解,从入门到放弃。文章目录STM32 IIC实验讲解,从入门到放弃。前言、IICIIC是什么?IIC协议二、代码部
    发表于 01-17 08:12

    IIC总线通信协议的理解及应用

    1.试题所需要协调的外设有:PCF8591、数码管、矩阵键盘、led、电位计RB2、AT24C02;2.难点和待解决的问题:(1)矩阵 按键的长按检测和单次按键检测(较难);(2)IIC总线
    发表于 01-19 07:56

    IIC的通信原理及分析IIC的真实波形

    IIC的通信原理。1 IIC基础知识首先复习IIC基础知识,这部分看不懂的请先带着疑问,然后我们通过分析
    发表于 02-24 06:01

    IIC总线协议

    IIC总线协议,感兴趣的小伙伴们可以看看。
    发表于 07-26 16:29 57次下载

    IIC总线协议及应用

    IIC总线协议及应用I2C总线知识I2C总线物理拓扑结构I2C总线特征I2C
    发表于 11-20 15:21 10次下载
    <b class='flag-5'>IIC</b><b class='flag-5'>总线</b><b class='flag-5'>协议</b>及应用

    STC89C52的IIC总线写EEPROM

    串行通信中的IIC总线工作原理51本身不带IIC总线 ,使用程序模拟IIC通信
    发表于 11-25 15:51 11次下载
    STC89C52的<b class='flag-5'>IIC</b><b class='flag-5'>总线</b>写EEPROM

    一文带你迅速了解常用串行总线IIC协议2

    集成电路总线** (Inter-Intergrated Circuit),通常称作IICBUS,简称为IIC,是一种采用多主从结构的串行通信总线I
    的头像 发表于 01-21 17:20 800次阅读

    一文带你迅速了解常用串行总线IIC协议3

    集成电路总线** (Inter-Intergrated Circuit),通常称作IICBUS,简称为IIC,是一种采用多主从结构的串行通信总线I
    的头像 发表于 01-21 17:20 801次阅读