I2C总线接口及时序

1. I2C接口学习要点

1.有2条双向串行线,一条数据线SDA,一条时钟线SCL

如果只做master SCL可以只是输出

SDA在PAD上一定是inout pin,当然转为数字信号时可以分为两组

inout    SDA;

input    sda_i;

output  sda_o;

wire sda_oen;

assign SDA = (sda_oen == 0) ? sda_o : 1'bz;

assign sda_i = SDA;

在GPIO的OD模式,输出三态缓冲门在输出高阻态时,SDA总线上是高电平,所以此时GPIO的oen可直接接sda_o,同时输出三态缓冲门输入接死为0,这样就不需要单独的oen信号。

实际与GPIO的连接可参考:

I2S和I2C分别如何连接pad_cy413026的博客-CSDN博客典型的pad及其接口如下图所示:一般情况下IE信号直接tie 1.因为大部分都不会做输入控制。https://blog.csdn.net/cy413026/article/details/128413260?csdn_share_tail=%7B%22type%22%3A%22blog%22%2C%22rType%22%3A%22article%22%2C%22rId%22%3A%22128413260%22%2C%22source%22%3A%22cy413026%22%7D

2.以1byte为数据传输单位,如果需要继续传输,需要数据接收端(可能是slave,也可能是master)在SDA上返回ACK

也就是说在发送8bit数据后 发送数据端会释放总线oen=1输出高阻,等待接收端在第9个SCL高电平时返回SDA=0,否则进入stop

3.输出SCL的是master

4.每个slave分配有地址,master要和某个slave通信时 在start之后紧跟着发送地址[7:1]+读写标识位[0],bit0 :1表示master写,0表示master读。

        所有slave接收到8bit 第一字节后,和第一字节的[7:1]地址比较,如果相同,则该slave在第9拍返回ACK。其他不匹配slave保持SDA为高。

        I2C支持广播,广播地址为0,收到0地址后,所有slave都需要继续接收数据。

5.I2C采样数据在SCL高电平,而不是边沿,所以SDA数据在SCL低电平时可以变化,在高电平保持

        逻辑上怎么实现的,scl的变化最终肯定是和clk相关的

        当某个I2C master发送bitRate和其他master的bitRate不一致时,能通过I2C的仲裁正确的传输吗

        电平采样怎么做的?是不是还是用scl的边沿采样?

        用寄存器锁存而不是latch锁存?

6.一旦在SCL的高电平期间 SDA发生变化,要么时start状态要么是stop状态

7.可以使用普通GPIO口模拟I2C,但要需要将GPIO配置成OD模式(开漏模式)

8.I2C是MSB先发送,LSB后发送

9.I2C是支持多master和多slave的总线

10.传输开始的start和传输结束的end都是由master发送的

2.接口时序

具体时序参考以下:

I2C协议靠这16张图彻底搞懂(超详细)_cy413026的博客-CSDN博客

上图给出了I2C从start开始发送8bit地址字节到收到ack过程的时序图。其中:

  1. ic_clk是I2C工作频率
  2. start_en:表示I2C传输开始
  3. tx_bit_count:对当前发送的bit计数。0-7是发送bit,8是检测ack
  4. ic_clk_oe:是输出接到pad OE端的输出scl_o
  5. ic_data_oe:是输出接到pad OE端的输出sda_0
  6. ack_det:是从pad C 端输出给I2C的输入sda_i经过同步处理和检测之后的一个标识检测到ack的标志信号
  7. scl_out_n:经过延迟取反后产生ic_clk_oe
  8. sda_hold_done:用来产生sda_out_n的控制信号
  9. sda_out_n:经过延迟取反后产生ic_data_oe信号
  10. sda_hold_count_r:是用来对scl_out_n拉高计数,记到配置值之后拉高sda_hold_done

        在I2C信号产生过程中,首先需要一个比bitRate高的多的工作频率ic_clk,这一点和I2S的实现需求是类似的。

        有了ic_clk我们先产生scl,scl的高低电平持续时间都是可以配置的;

        ic_clk和scl的高低电平持续时间可以根据当前I2C是normal/fast/High模式来设置。

        数据信号的timing是 scl高电平保持,低电平变化,对应scl_out_n是高电平变化,低电平保持,那么在产生了scl_out_n信号之后,对scl_out_n的上升沿进行delay,下降沿不变,产生sda_hold_done信号,那么sda_out_n信号的每次变化保证在sda_hold_done的上升沿即可。

3.I2C总线

   

 I2C串行的8位双向数据传输速率有多个档次:

  1. 在标准模式下可达100Kbit/s
  2. 快速模式下可达400Kbit/s
  3. 高速模式下可达3.4Mbit/s

        总线具有极低的电流消耗,抗噪声干扰能力强,增加总线驱动器可以使总线电容扩大10倍,传输距离达到15m;兼容不同电压等级的器件,工作温度范围宽。

        I2C是一个多master多slave的总线,这样就存在多master对总线的竞争,slave是不会主动发起请求的。

        因为master发起传输时,首先要检查总线处于空闲状态,总线为空闲时,必先发start。这个时候就存在master1 发起了start,在start传输到总线上,并被其他master稳定检测到之前,master2发起了start,这时就发生了竞争。

        需要注意的是: 当SCL和SDA都为1且持续时间达到协议要求的tBUF时间才认为是空闲状态,否则可能会误判传输bit1为空闲。

        所有的传输都以start开始,以stop结束,但是如果连续传输,master可以不发stop,直接重新启动直接发start【叫做re-start】

  • 问题1:I2C总线是如何解决多请求之间的仲裁呢?
  • 问题2:没有被仲裁到的master该怎样处理?
  • 问题3:既然是总线就要接受反压,master在发起读写请求的时候并不知道slave是否准备好接收数据或发送数据,在master发起了start并发送地址之后,slave并没有准备好,这时该怎么处理? 

        I2C是以byte为单位传输的,每传输完一个byte,slave对于下一个byte的接收和发送是否准备好,都是未知的,这个时候该怎么办呢?

  • 问题4:不同速率的I2C怎么互相兼容呢?

     先给出I2C总线在处理竞争,拥堵及兼容的三个机制

  1. “线与”机制。多主机时,总线具有“线与”的逻辑功能,即只要有一个节点发送低电平时,总线上就表现为低电平。
  2. SDA回读机制。总线被启动后,多个主机在每发送一个数据位时都要对自己的输出电平进行检测,只要检测的电平与自己发出的电平一致,就会继续占用总线。
  3. 低电平优先机制。由于线与的存在,当多主机发送时,谁先发送低电平谁就会掌握对总线的控制权。

     对应的几个解决上述问题的操作有时钟同步,总线总裁和时钟拉伸,读完下面的文章对上面提出的问题就会有答案。下面分章节介绍:

【内容摘自:

彻底搞懂I2C总线(2)标准模式、快速模式下的I2C通信协议 - 知乎

3.1 I2C 时钟同步

图1-24 I2C总线时钟同步

        在空闲总线时,两个主机可以同时启动传输,必须有一种方法来决定由哪一个主机来控制总线并完成传输。这是通过时钟同步和仲裁两个步骤来完成的。在一主多从的系统中,不需要时钟同步和仲裁。

        参考图1-24,使用设备的SCL接口和SCL总线之间的“线与”连接来执行时钟同步。主机一的SCL接口一旦检测到SCL总线上由高电平到低电平的转换时,主机一便拉低自己的SCL,并开始倒计数应有的SCL低电平保持时间,直到应有的低电平时间结束,便把SCL时钟拉到高电平状态。如果另一个主机二的SCL时钟仍然处于低电平周期内,则主机一的SCL时钟由低到高的转换不会改变SCL总线为低电平的状态,则主机一的SCL时钟进入高电平等待状态。因此,SCL总线被具有最长低电平周期的主机保持在低电平。

        当所有相关的主机都已完成其低电平周期的计数时,SCL时钟总线被释放并变为高电平。主机SCL接口和SCL总线的状态之间保持一致,都为高电平。所有主机开始计算它们的高电平周期。第一个完成高电平周期的主机再次将SCL线拉低。

        这样,就产生了同步的SCL总线时钟,其低周期由具有最长时钟低周期的主机确定,其高周期由具有最短时钟高周期的主机确定。

3.2 I2C总线仲裁

        设备的SDA接口线每次输出电平后,会立即回读SDA总线电平,用来判断自己的输出是否与总线一致。SCL线和SDA一样,也有这种回读判读机制。

        仲裁协议用于多主机的系统中,单主机系统不需要仲裁。仲裁程序发生在主机之间,从机不涉及仲裁。只有当总线空闲时,主机才可以启动传输。两个主机同时发起启动后,总线需要对这两个主机进行仲裁,以确定最终由哪个主机控制总线并完成其传输。

        仲裁由SCL线和SDA线一起配合来完成的,其分工如下:

        SCL线负责时钟同步(参考图1-24):两个主机在空闲状态时,同时发起启动,然后各自根据自己的时序要求拉低SCL总线输出低电平,释放SCL总线输出高电平,根据前面章节介绍的SCK时钟同步机制实现时钟同步。

        SDA线负责数据仲裁(参考图1-25):仲裁是在SDA线上一位一位地进行的。在每一位传输期间,当SCL为高电平时,每个主机各自判断自己SDA线输出的电平是否与SDA总线电平一致(回读判读机制),如果某主机发现输出电平和回读电平不一致,则该主机仲裁失败,失去对总线的控制权,随即关闭自己SDA输出驱动器,另一个主机赢得仲裁获取对总线的控制权,继续完成它的传输事务。这种仲裁过程可能需要进行很多位。

图1-25 I2C总线仲裁

        在仲裁过程中,赢得仲裁的主机不会丢失任何信息,仲裁失败的主机可以继续产生时钟脉冲,直到其仲裁失败的字节结束,并且可以在总线空闲时重新发起仲裁。也可以在lost arbitrary之后直接将scl和sda拉高

        如果一个主机也具有从机的功能,并且在寻址阶段仲裁失败,那么获胜的主机可能正在尝试寻址它。因此,失败的主机必须立即切换到其从机模式。

        根据连接到总线的主机数量,以上的仲裁方式也适合更多主机的系统。

        由于对I2C总线的控制完全由参与竞争的主机发送的地址和数据决定,所以总线上没有中央控制器,也没有任何优先级顺序。

        当一个主机发送重启或停止信号时,而另一个主机仍在发送数据时,如果仲裁程序仍在进行中,则会出现未定义(异常)的状态。换句话说,以下组合会导致异常情况:

        主机1发送重启信号,主机2发送数据位(所以重启前一定要判断重启建立时间tSU;STA)。

        主机1发送停止信号,主机2发送数据位。

        主机1发送重启信号,主机2发送停止信号。

3.3 时钟拉伸(Clock stretching)

        在传输一个字节时,从机可能能够快速接收数据字节,但需要更多时间来存储接收到的字节或准备要传输的字节,如果基于以上原因无法立即进行下一个字节的传输时,那么从机在接收完一个字节并应答后,slave可以将SCL线的低电平继续拉低并保持【需要具有slave驱动scl的能力】,以强制主机进入等待状态,直到从机做好了传输下一个字节的准备(参见图1-26)。

图1-26 时钟拉伸

        时钟拉伸通过将SCL线保持在低电平来暂停传输,直到SCL总线路再次被释放为高电平,这样可以实现高低速器件兼容。时钟拉伸是可选的,事实上,大多数从机设备不具有SCL驱动程序,因而不具有拉伸时钟的功能。

3.4 startByte

本节摘自I2C中START BYTE?为什么需要START BYTE?_i2c start byte_小小verifier的博客-CSDN博客

如果I2C master和slave支持startByte,在主状态机中就应该有该过程的体现

3.4.1 什么是START BYTE?

        START BYTE会将开始条件的过程延长,就是在I2C生成START 条件之后,继续发送1个byte字节信号(0000_0001),master持续的将SDA线拉低7个周期。

3.4.2 为什么要发送startByte

        I2C总线上至少要有一个master(微控制器或者DSP)连接,如果微控制器具有片上硬件I2C总线接口,那它可以被编程为只能被总线的请求中断。当微控制没有这样的接口时,它必须不断地通过软件来监控总线,不断地轮询或监视总线的行为,这势必影响了数据传送的安全性,也增加了功耗。在这种情况下,如果采取正常情况下的start条件(在SCL为高期间,SDA由高拉低),这个过程相对是很短暂的,微控制器可能监视不到这个start条件。所以,在数据传输之前,为了确保微控制器可以采样到总线上的START条件,可以使用一个比正常情况长得多的start过程(发送0000_0001),以此便于微控制器以较低的频率采样SDA线。当微控制器检测到起始字节中的七个0中的任意一个0时,就可以切换到更快的速率,找到0000_0001之后的重复启动(Sr)条件,然后开始之后的传输。

3.4.3怎么开启START BYTE?

START BYTE的过程:

  • maser先产生一个START条件;
  • maser发送start byte(0000_0001) ;
  • start byte字节传输之后的一拍,不能有任何slave响应ACK
  • master产生一个restart条件。

3.5 I2C设备的运行状态机

I2C master定义了以下状态:

IDLE
GEN_START    区分后续是正常的slave地址还是 general call或startByte。其中general call 地址就是8'h00 广播地址
POP_TX_DATA
CHECK_IC_TAR //check the target slave address.确定后续是发送general call还是startByte
RX_BYTE
GEN_STOP
TX7_1ST_ADDR
TX10_1ST_ADDR
TX10_2ND_ADDR
GEN_RSTART_SBYTE    //gen re-start condition to change the direction of the transaction
TX_BYTE
GEN_RSTART_10BIT
GEN_RSTART_7BIT
GEN_SPLIT_STOP      // 用在SS和FSmode ?什么是SS和FS?
GEN_SPLIT_START     // 用在SS和FSmode ?什么是SS和FS? 当re_start disabled后,用于产生一个start来分开连续transaction?
HOLD_TX_BYTE
HOLD_RX_BYTE

I2C slave定义了以下状态:

IDLE
RX_1BYTE            // Receive 1st byte
RX10_2ND_ADDR       // Receive the 2nd byte of 10 bit addr
RX_LOOP             // Receive data loop
TX_LOOP             // Transmit data loop
WAIT_TX_DATA        // wait for processor to supply data for slv TX
ABORT_RX_ADDR       // address reception aborted due to START
INSPECT_DATA_CMD    // check bit 8 of IC_DATA_CMD
WAIT_RX_FULL        // wait for Receive fifo has some space

4.参考文献

原创地址:

彻底搞懂I2C总线(2)标准模式、快速模式下的I2C通信协议 - 知乎

嚼烂I2C之 I2C为啥要这样设计? - 知乎

转载地址:

彻底搞懂I2C总线(2)标准模式、快速模式下的I2C通信协议-CSDN博客

嚼烂I2C之 I2C为啥要这样设计?-CSDN博客

  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
I2C总线(Inter-Integrated Circuit Bus)是一种串行通信协议,用于连接微控制器和外部设备,如传感器、存储器和其他外围设备。使用Verilog语言实现I2C总线通信需要以下步骤: 1. 首先,根据I2C总线的规格制定Verilog模块。根据I2C规范,定义模块的输入和输出信号,包括时钟信号(SCL),数据信号(SDA)和其他控制信号。 2. 确定I2C总线时序。根据I2C规范,定义时钟信号和数据信号的传输速率以及数据传输的起始、停止和数据位的格式。 3. 实现I2C总线的控制逻辑。使用Verilog语言编写控制模块,根据时序要求生成适当的控制信号,如起始信号、停止信号、读写信号以及ACK(应答)信号。 4. 实现I2C总线的状态机。根据I2C总线的协议规范编写状态机,以确保正确的数据传输和通信序列。状态机可以用有限状态机(FSM)的形式实现。 5. 实现I2C总线的数据传输。编写适当的代码,根据I2C规范中的传输顺序和协议,将数据从发送方传输到接收方,并确保数据的完整性和准确性。 6. 仿真和验证。使用仿真工具,如ModelSim,对Verilog代码进行仿真和验证,以确保I2C总线的正常工作和正确性。 通过以上步骤,可以使用Verilog语言实现I2C总线,并用于连接微控制器和外设设备之间的通信。实现的I2C总线可以支持数据传输、控制信号和时序要求,并且可以确保数据的完整性和可靠性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值