I2C的爱恨情仇
开篇
上次写了 I2C 发包与测试后,决定细讲一下 I2C 协议,也作为自己的一个笔记,以后有些东西忘记了常来翻翻。
这是百度百科的介绍
I2C 总线是由 Philips 公司开发的一种简单、双向二线制同步串行总线。它只需要两根线即可在连接于总线上的器件之间传送信息。
主器件用于启动总线传送数据,并产生时钟以开放传送的器件,此时任何被寻址的器件均被认为是从器件.在总线上主和从、发和收的关系不是恒定的,而取决于此时数据传送方向。如果主机要发送数据给从器件,则主机首先寻址从器件,然后主动发送数据至从器件,最后由主机终止数据传送;如果主机要接收从器件的数据,首先由主器件寻址从器件.然后主机接收从器件发送的数据,最后由主机终止接收过程。在这种情况下.主机负责产生定时时钟和终止数据传送。
通过介绍来看,我们知道 I2C 是个在电子领域非常常用的一种协议,一个主机下可以挂多个从机。因为他的电路非常简单,设计也很巧妙,只需要两根线就可以实现,不需要特殊的接口电路,总结就是在简化布线、降低成本的同时也有很好的稳定性。
5种速率
I2C 的五种工作模式如下所示,最常用得到的就是100K的了
- 标准模式(Standard):100 kbps
- 快速模式(Fast):400 kbps
- 快速模式+(Fast-Plus):1 Mbps
- 高速模式(High-speed):3.4 Mbps
- 超快模式(Ultra-Fast):5 Mbps(单向传输)
介绍完之后,下面进入正题,我也不知道会分几步来说,想到哪说到哪把,以下的资料都是在 IIC 协会手册(IIC 手册)上的加上自己的理解,有部分我自己也模模糊糊,发出来一起学习把,有错误帮忙指出下各位看官老少爷们~~
一、时序
时序及特性
如图为网上找的 IIC 时序图,这张图还是比较全面的。
结合 IIC 手册直接总结经验
起始信号: I2C 协议规定,SCL处于高电平时,SDA 由高到低变化,这种信号是起始信号
停止信号: I2C 协议规定,SCL处于高电平,SDA 由低到高变化,这种信号是停止信号
读写信号: I2C 协议规定,当第 8 个始终周期的时候,SDA 为高电平时为读(1);SDA 为低电平时为写(0)
数据有效性: I2C 协议对数据的采样发生在 SCL 高电平期间,除了起始和停止信号,在数据传输期间,SCL 为高电平时,SDA 必须保持稳定,不允许改变,在 SCL 低电平时才可以进行变化,即时钟高电平采样
ACK/NACK信号: 在第 9 个时钟周期的时候,如果读取到 SDA 为低电平,则说明数据被从机成功接收到,可进行下一步操作。若 SDA 为高电平,说明数据未被应答,没有成功的建立通信,需进一步寻找原因
在这几点的基础上再来看这张图就很清晰明了了。
由此我们可以读出地址、读写情况、数据等信息。
上面有说到 IIC 是可以进行一个主机和多个从机进行收发数据的,在单主设备中,不需要时钟同步和仲裁。而在多设备时,多个主设备可以同时在空闲的总线上开始发送数据,这时就需要仲裁决定哪一个来控制总线并完成它的数据传输,有时候也需要时钟同步来协同设备间的工作。而这正是通过时钟同步和仲裁来完成的。
时钟同步
有的时候,主机的速度快于从机的速度,或者从机需要处理其他事情而不能及时地从主机接收数据或者向主机发送数据。如果从设备希望主设备降低传输速率,可以通过将 SCL 主动拉低,延长 SCL 低电平时间的方法来通知主设备。当主设备下一次传输时发现SCL电平被拉低时,就进入等待,直到从设备完成操作并释放 SCL 线。这就要使用时钟同步来完成。
时钟同步是通过连接到 SCL 总线的 I2C 接口 “线与” (全一为一,有零为零)实现。
SCL线上的低电平时间是由时钟低电平最长的器件决定,SCL 的高电平则是由高电平时间最短的期间决定。
时钟同步解决了 I2C 总线设备间的速度同步。
时钟同步的过程:
一旦主设备1的时钟拉低,就会把 SCL 总线拉低。当 SCL 总线从高拉低时,主设备将计数主设备时钟的低电位周期。
主设备2 检测到 SCL 线为低,也会立刻将 CLK1 拉低,不会等到 CLK1 的正常周期才拉低。
如果此时另外一个主设备的时钟仍然是低电平的,此时 SCL 总线也同样的保持为低。在此期间,低周期比较短的主设备1 将进入高电平状态等待。如图,主设备1 提前进入高电平等待,主设备2 继续保持低电平。
当所有主设备的时钟都为高电平时,将会把 SCL 线拉高。也就是说时钟低电平周期较长的主设备2 决定了 SCL 线为低的周期长度。
所有的主设备时钟都拉高时,将对他们的高电平时钟计数,第一个结束时钟高电平周期的主设备将会把 SCL 线拉低。主设备2 将 SCL 拉低后,主设备1 检测到 SCL 线为低时,CLK1 也立刻拉低。
总线仲裁
仲裁和同步是一样的,只有在系统使用多个主设备时才需要,而从设备(slave)不参与仲裁程序。当然,只有在主线空闲的情况下,主设备才可以发起传输。两个主机可以在启动条件的最小保持时间内生成一个启动条件,从而在总线上生成一个有效的传输启动条件,然后仲裁程序决定哪一个主设备可以完成它的传输。
谁先在 SDA 线上发送低电平,谁就掌握对总线的控制权。
由于 I²C 总线的控制只由地址或主机码以及竞争主机发送的数据决定,没有中央主机,总线也没有任何定制的优先权。
必须特别注意的是:在串行传输时,当重复起始条件或停止条件发送到I²C 总线的时侯,仲裁过程仍在进行。如果可能产生这样的情况,有关的主机必须在帧格式相同位置发送这个重复起始条件或停止条件。也就是说,仲裁在不能下面情况之间进行:
- 重复起始条件和数据位
- 停止条件和数据位
- 重复起始条件和停止条件
仲裁的过程:
当两个 master 对同一个地址的 slave 进行传输时,多个 master 会都进入数据周期,仲裁会单比特对单比特进行比较。在 SCL 为高的每一个比特位期间,每个主设备检查 SDA 线的电平是否与它所发送的相匹配。这个过程很可能需要比对很多位。如果传输的数据时完全相同的,则这个主设备可以完成地发送整个事务。
当主设备发送的比特位与 SDA 线不匹配时,例如图中 DATA1 在 SCL 线的第三个周期,此时 DATA1 拉高,而 DATA2 为低,DATA1 和 DATA2 在“线与”后 SDA 为低,匹配不成功。当主设备1 检测到一个与自身不相符的低电平,这时会关闭主设备1 的 SDA 传输驱动,另一个主设备2 会继续完成传输。
根据上面的描述得出:
- 对于整个仲裁过程主控器1和主控器2都不会丢失数据;
- 各个主控器没有对总线实施控制的优先级别;
- 总线控制随即而定,他们遵循“低电平优先”的原则,即谁先发送低电平谁就会掌握对总线的控制权。
“时钟同步”与“总线仲裁”可以总结如下规律:
主控器通过检测SCL上的电平来调节与从器件的速度同步问题——时钟同步;
主控器通过检测SDA上自身发送的电平来判断是否发生总线“冲突”——总线仲裁。因此,I2C总线的“时钟同步”与“总线仲裁”是靠器件自身接口的特殊结构得以实现的。
二、地址
保留地址
下表为 I2C 规范保留的两组 1111XXX
和 0000XXX
和 8 个地址。这些地址用于特殊用途。
从机地址 | R/W | 描述 |
---|---|---|
0000 000 | 0 | 呼叫地址 |
0000 000 | 1 | 起始字节 |
0000 001 | X | CBUS地址 |
0000 010 | X | 保留供不同的总线格式 |
0000 011 | X | 保留将来用 |
0000 11X | X | HS模式主机码 |
1111 0XX | X | 10位从机地址 |
1111 1XX | X | 保留将来用 |
X = don’t care; 1 = HIGH; 0 = LOW |
IIC 地址也分为 8 位地址(加上第八位读写位)或 7 位地址(不加读写位),如上表格所示,有的 IIC 器件也支持 10 位地址的。
下面为手册上的 10 位地址的读写操作
I2C 总线的 10 bit 寻址和 7 bit 寻址是兼容的,这样就可以在同一个总线上同时使用 7 bit 地址和 10 bit 地址模式的设备,在进行 10 bit 地址传输时,第一字节是一个特殊的保留地址来指示当前传输的是 10 bit 地址
三、电路
每一个IIC总线器件内部的SDA、SCL引脚电路结构都是一样的,引脚的输出驱动与输入缓冲连在一起。其中输出为漏极开路的场效应管、输入缓冲为一只高输入阻抗的同相器。
这种电路具有两个特点:
1. 由于SDA、SCL为漏极开路结构,借助于外部的上拉电阻实现了信号的“线与”逻辑;
2. 引脚在输出信号的同时还将引脚上的电平进行检测,检测是否与刚才输出一致。为 “时钟同步”和“总线仲裁”提供硬件基础。
那为什么 I2C 要用到漏极开路和上拉电阻呢?
IIC协议支持多个主设备与多个从设备在一条总线上, 如果不用开漏输出, 而用推挽输出, 会出现主设备之间短路的情况. 至于为什么需要上拉电阻, 那是因为IIC通信需要输出高电平的能力.
四、Spec介绍
下面是测试人员最需要关注的一页了,Electrical specifications and timing
对上面部分参数的解释如下
VIH/VIL的解释:
输入电平若在 VIL(max)~0之间,即输入电平为低电平
输入电平若在 VIH(min)~VDD之间,即输入电平为高电平
VIL(max)为低电平的门限电平;VIH(min)为高电平的门限电平
建立保持时间的解释:
建立时间(Tsu): 在时钟采样沿之前,数据必须保持稳定的最短时间。
保持时间(Th): 在时钟采样沿之后,数据必须保持稳定的最短时间。
暂时先写到这里吧,感觉写着写着就停不下来了,有好多东西都能无限的扩展,说多了就烦了,再加上水平技术也有限,暂时就这些吧。
参考 IIC 电气手册,部分资料来自baidu CSDN 博客园等个各大佬