目录
一、I2C 简介
I2C总线是一种同步、半双工双向的两线式串口总线。它由两条总线组成:串行时钟线SCL和串行数据线SDA。I2C 总线有两种模式,标准模式下速度可以达到100Kb/s,快速模式下可以达到400Kb/s。
- SCL:负责产生时钟脉冲。(由主设备控制,即由发送的一方控制)
- SDA:负责数据的传输。(主、从设备都可以使用)
I2C 支持多从机,一个I2C控制器下可以挂多个I2C 从设备,不同从设备有不同的器件地址,I2C主控制器可以通过器件地址访问指定的 I2C 设备。
二、I2C 的整体通信流程
当总线处在空闲状态下,总线上任一设备都可以发起通信。发起通信的一方就是“主机”,主机指定通信的设备就是“从机”。主从机的整体通信流程如下:
① 准备阶段
- 主机发起开始信号占用总线(开始条件)
- 主机发送一个字节的数据,指定通信设备和通信方向(地址传送)—— 要和哪个设备通信
- 被寻址的设备发送一个应答信号回应主机(应答条件)
- 主机发送一个字节的数据,指定寄存器地址(地址传送)—— 要读/写目标设备的哪个寄存器
- 被寻址的设备发送一个应答信号回应主机(应答条件)
② 数据传输阶段
- 发送方发送一个字节数据(数据传输)
- 接收方接收到数据以后发送一个应答信号(应答条件)
③ 结束阶段
- 主机发送停止信号释放总线(停止条件)
三、通信协议
当总线处在空闲状态下,总线上任一设备都可以发起通信。(SCL 为高电平,SDA 为高电平)
3.1 开始 / 停止条件
SCL 为高电平,SDA 出现了下降沿的时候,此时表示总线上某个设备要开始通信了。
SCL 为高电平,SDA 出现了上升沿的时候,此时表示设备通信结束,释放总线。结束通信有两种情况:
- 主机读取完从机数据,返回一个ACK以后,不继续发了
- 从机读取完主机数据,返回一个NACK,表明自己不想收了
3.2 地址传送
开始通信以后,主机(发起通信的一方)向总线上发送一个字节的数据帧,相当于在广播寻人,这帧内容包含:
- 通信设备地址:表明主机想和谁通信。一般是7 bit,有些标准是 9 bit
- 通信方向:决定了接下来的一次数据传输,是读寄存器还是写寄存器,还是准备收数据。0 表示写(发送),1 表示读(接收)
注意:阴影部分表示主机发送的,白色部分表示从机发送的。
3.3 数据传输
主机收到从机发送的应答信号以后,表明可以开始数据传输了。通信方向如果是“写”,主机发送数据;如果通信方向是“读”,从机发送数据。数据帧占 8 bit(1个字节)。白色部分为 DATA,表示从机发送数据;阴影部分是 A,表示主机对数据做出了应答。
注意:SCL 为低电平时,可以无需顾忌SDA的边沿变化,但是 SCL 处于高电平时,发送的数据不能有任何边沿变化。
3.4 应答条件
每当有一方向总线发送了数据,另一方必须发出应答信号表示自己已经收到。应答信号占 1 bit,分为 ACK 和 NACK。
- ACK:表示接收方可以继续通信。SCL 为高,SDA 为低
- NACK:表示接收方不想继续通信。SCL 为高,SDA 为高;或者发送开始信号,启动新一轮的通信
产生应答一般有两种情况:地址传输、数据传输
3.5 重复开始条件
在没有发出停止条件的情况下,开始条件可以在通信期间重复出现,这是一种特殊情况。一般用于改变通信传输方向、尝试重复传输等情况。
四、通信时序
在第二部分已经了解了整体通信流程,下面我们要结合上面的通信协议,进一步了解 I2C 协议的读写过程。
1、写时序
① 发送开始信号。
② 主机发送通信设备地址(7 bit)、通信方向(1 bit),从机作出响应
③ 主机发送寄存器地址(8 bit),从机作出响应(若寄存器地址大于一个字节,需多次发送)
④ 寄存器地址全部发送完毕,才能开始发送数据。
⑤ 因为是写时序,主机要写寄存器,这里无需改变通信方向,主机可直接发送要写入的数据
⑥ 从机作出响应
⑦ ... ... (如此往复)
⑧ 发送停止信号。
2、读时序
读时序最开始的通信方向也是“写”,因为一开始需要告诉从机,自己想读哪个寄存器的地址。发送完毕以后。然后再坐等从机“写”,即从机发送数据。
① 发送开始信号。
② 主机发送通信设备地址(7 bit)、通信方向为写(1 bit),从机作出响应
③ 主机发送寄存器地址(8 bit),从机作出响应(若寄存器地址大于一个字节,需多次发送)
④ 寄存器地址全部发送完毕,才能开始发送数据。
⑤ 因为是读时序,主机要读寄存器,需要先改变通信方向,发送重复开始信号,
⑥ 从机作出响应
⑦ 主机发送寄存器地址,从机作出响应
⑧ 从机发送数据,主机作出响应
⑨ ... ... (如此往复)
⑩ 发送停止信号
五、总线仲裁机制(SDA)
1、什么是总线仲裁
当一小段起始时间内,有两个及以上的主机产生了开始信号,此时需要通过仲裁决定最终由哪个主机占用总线。仲裁规则如下:
- 当 SCL 为高电平时,让主机产生的信号进行“线与”(按位与)
- 第 n 个周期:每个主机检测 “线与”的结果是否和自己产生的电平一致
- 如果一致,则继续占用总线
- 如果不一致,则退出仲裁
- ... ...
- 直至总线上只剩下一个产生开始信号的主机
2、总线仲裁的过程
假设某一小段时间内,SCL 处于高电平时,主机DATA1、主机DATA2向总线发送了起始信号(产生了下降沿),此时要对主机DATA1、主机DATA2进行冲裁。
SCL 的第一个周期内的高电平到来,DATA1 和 DATA2 线与的结果是高电平,DATA1为高电平,和线与结果一致,DATA2也为高电平,双方继续占用总线(继续仲裁)
SCL 的第二个周期的高电平到来,DATA1 和 DATA2 线与的结果是低电平,DATA1为低电平,和线与结果一致,DATA2也为低电平,双方继续占用总线(继续仲裁)
SCL 的第三个周期的高电平到来,DATA1 和 DATA2 线与的结果是低电平,DATA1为高电平,和线与结果不一致,退出仲裁;DATA2为低电平,和线与结果一致。
因此,DATA2 在仲裁中胜出,继续占用总线。
六、时钟同步(SCL)
有的时候,主机的速度快于从机的速度,或者从机需要处理其他事情而不能及时地从主机接收数据或者向主机发送数据。如果从设备希望主设备降低传输速率,可以通过将 SCL 主动拉低,延长SCL 低电平时间的方法来通知主设备。
由于“线与”的机制,即便有多个设备节点向总线发送时钟信号,但是在总线上表现的是统一的时钟信号。
参考文章:
一文搞懂I2C通信总线_i2c通信的详细讲解_不脱发的程序猿的博客-CSDN博客
I2C总线协议详解(特点、通信过程、典型I2C时序)_zhangduang_KHKW的博客-CSDN博客