2. I2C通信协议详解:起始条件、停止条件、数据有效性、字节格式、应答与非应答机制
I2C(Inter-Integrated Circuit)总线协议由Philips(现NXP)设计,是一种同步、多主从、半双工的串行通信协议。它仅需两根线——串行数据线(SDA)和串行时钟线(SCL)——即可完成设备间的数据交换。本章将深入剖析I2C协议的核心时序单元,为后续编写Linux I2C驱动打下坚实的硬件基础。
2.1 总线空闲状态与电气特性
在开始分析具体时序之前,必须先明确总线的空闲状态。I2C总线采用开漏(Open-Drain)结构,这意味着任何设备都可以将SDA或SCL线拉低,但无法主动驱动为高电平。高电平由外部上拉电阻提供。
| 状态 | SDA电平 | SCL电平 | 说明 |
|---|---|---|---|
| 空闲(Idle) | 高(H) | 高(H) | 总线释放,无设备占用 |
| 起始条件(S) | 高→低 | 高 | SCL为高时,SDA由高变低 |
| 停止条件(P) | 低→高 | 高 | SCL为高时,SDA由低变高 |
| 数据有效 | 稳定 | 高 | SCL高电平期间,SDA数据必须稳定 |
2.2 起始条件(START Condition)与停止条件(STOP Condition)
起始条件和停止条件是I2C通信的“帧头”和“帧尾”,由主机(Master)产生。所有从机(Slave)都持续监听总线,检测到起始条件后开始准备接收地址,检测到停止条件后复位内部状态机。
2.2.1 起始条件(S)
当SCL线为高电平时,SDA线从高电平切换到低电平。这个下降沿标志着一次I2C传输的开始。起始条件之后,总线被主机占用,其他设备不得发起传输。
2.2.2 停止条件(P)
当SCL线为高电平时,SDA线从低电平切换到高电平。这个上升沿标志着传输的结束。停止条件之后,总线恢复空闲状态,允许其他主机竞争总线。
2.2.3 重复起始条件(Sr)
在未产生停止条件的情况下,主机可以再次产生一个起始条件。这在多字节读写或改变数据方向(如从写地址切换到读数据)时非常有用,避免了总线释放后被其他主机抢占。
2.3 数据有效性(Data Validity)
I2C协议规定,在SCL时钟的高电平期间,SDA线上的数据必须保持稳定。只有在SCL为低电平时,SDA上的数据才允许发生变化。这一规则确保了数据采样的可靠性。
- SCL高电平: 数据采样窗口。接收方在SCL上升沿或高电平期间读取SDA电平。
- SCL低电平: 数据变化窗口。发送方在SCL低电平期间更新SDA电平,为下一个数据位做准备。
2.4 字节格式与数据传输
I2C总线上的数据以字节(8位)为单位进行传输。每个字节后必须跟随一个应答位(ACK/NACK)。数据传输时,高位(MSB)在前,低位(LSB)在后。
2.4.1 标准字节传输流程
- 起始条件(S):主机产生起始条件。
- 发送7位从机地址 + R/W位:主机发送8位数据(高7位为地址,最低位为读写方向)。
- 从机应答(ACK):如果地址匹配,从机在第9个SCL周期拉低SDA作为应答。
- 发送/接收数据字节:根据R/W位,主机或从机发送8位数据。
- 应答/非应答:接收方在第9个SCL周期给出应答。
- 停止条件(P):主机产生停止条件,结束传输。
2.4.2 字节格式示意图
2.5 应答(ACK)与非应答(NACK)机制
应答机制是I2C协议可靠性的核心。每个字节传输完成后,接收方必须在第9个SCL周期给出反馈。
2.5.1 应答(ACK)
- 定义: 在第9个SCL周期,接收方将SDA线拉低。
- 含义: “我已成功接收到上一个字节,可以继续发送下一个字节。”
- 场景: 地址匹配成功、数据写入成功、数据读取请求被接受。
2.5.2 非应答(NACK)
- 定义: 在第9个SCL周期,接收方保持SDA线为高电平(不拉低)。
- 含义: “我无法接收更多数据”或“我未识别到该地址”。
- 场景: 从机忙、地址错误、读操作结束(主机主动发送NACK以通知从机停止发送)。
| 角色 | 发送ACK条件 | 发送NACK条件 |
|---|---|---|
| 从机(Slave) | 地址匹配成功;数据写入成功 | 地址不匹配;数据写入失败;从机忙 |
| 主机(Master) | 希望继续接收数据 | 已接收足够数据,准备停止传输 |
i2c-tools中的i2cdetect命令可以扫描总线上的设备地址。如果某个地址返回NACK,说明该设备不存在或地址错误。在驱动中,可以通过检查i2c_msg的返回状态来区分ACK/NACK错误。
2.6 完整数据传输流程示例
以下是一个完整的I2C写操作时序示例,展示了起始条件、地址、数据、应答和停止条件的组合。
2.7 高速模式与协议变体
标准I2C模式(100 kbps)和快速模式(400 kbps)是最常用的。此外,还有高速模式(3.4 Mbps)和超快速模式(5 Mbps),但时序要求更严格,通常需要硬件I2C控制器支持。
| 模式 | 最大速率 | 驱动关注点 |
|---|---|---|
| 标准模式(Sm) | 100 kbps | 通用,软件模拟(Bit-banging)也可实现 |
| 快速模式(Fm) | 400 kbps | 需注意上升时间,通常使用硬件控制器 |
| 高速模式(Hs) | 3.4 Mbps | 需专用I2C控制器,从机必须支持Hs模式 |
clock-frequency属性设置I2C总线速率。例如:clock-frequency = <400000>; 表示设置为400 kbps快速模式。驱动初始化时会根据该值配置控制器分频系数。