1. I2C协议基础:总线物理层特性、信号时序与起停条件

1.1 I2C总线物理层特性

I2C(Inter-Integrated Circuit)总线是一种由Philips(现NXP)开发的两线式串行通信总线,广泛应用于嵌入式系统中连接微控制器与低速外设。其物理层采用开漏(Open-Drain)结构,通过外部上拉电阻实现线与逻辑。

特性 说明 典型值
信号线数量 2根:SDA(数据线)、SCL(时钟线) 2
电气结构 开漏输出 + 外部上拉电阻 4.7kΩ(100kHz)/ 2.2kΩ(400kHz)
逻辑电平 低电平=GND,高电平=VDD(由上拉电阻决定) 3.3V / 5V
最大总线电容 限制从设备数量和总线长度 400pF
设备寻址 7位或10位地址,广播地址0x00 7位(最多112个节点)
通信模式 主从模式,多主支持(仲裁机制) 单主/多主
QNX驱动开发要点:在QNX I2C驱动中,物理层参数(上拉电阻、总线电容、电平转换)直接影响通信可靠性。驱动初始化时必须正确配置GPIO复用模式为开漏输出,并确保上拉电阻值匹配总线负载。

1.2 SDA与SCL信号时序

I2C总线的时序由SCL时钟信号和SDA数据信号共同定义。所有数据传输均在SCL为低电平时改变SDA状态,在SCL为高电平时采样SDA数据。标准模式(100kHz)、快速模式(400kHz)和高速模式(3.4MHz)的时序参数不同。

时序参数 符号 标准模式 (100kHz) 快速模式 (400kHz) 说明
SCL时钟频率 fSCL 100 kHz 400 kHz 总线时钟速率
SCL低电平时间 tLOW 4.7 μs 1.3 μs SCL保持低电平的最小时间
SCL高电平时间 tHIGH 4.0 μs 0.6 μs SCL保持高电平的最小时间
SDA数据建立时间 tSU;DAT 250 ns 100 ns SDA在SCL上升沿前必须稳定的时间
SDA数据保持时间 tHD;DAT 0 ns 0 ns SDA在SCL下降沿后必须保持的时间
上升时间 tr 1000 ns 300 ns SDA/SCL信号上升沿时间
下降时间 tf 300 ns 300 ns SDA/SCL信号下降沿时间
时序调试技巧:在QNX系统下,使用i2c-tools或自定义驱动调试接口测量SCL频率。若发现通信不稳定,优先检查SCL低电平时间是否满足规格,这是最常见的时序违规点。

1.3 起始条件与停止条件

I2C总线的数据传输由起始条件(START)和停止条件(STOP)界定。这两个条件是总线上的特殊信号序列,用于标识通信帧的开始和结束。

  • 起始条件(S):SCL为高电平时,SDA从高电平切换到低电平。主设备在传输前必须产生起始条件。
  • 停止条件(P):SCL为高电平时,SDA从低电平切换到高电平。主设备在传输完成后产生停止条件。
  • 重复起始条件(Sr):在未产生停止条件的情况下,再次产生起始条件。用于改变数据传输方向或切换从设备。
常见故障点:起始条件和停止条件的时序违规是I2C通信失败的常见原因。在QNX驱动中,若SCL高电平时间不足(tHIGH < 4.0μs @100kHz),从设备可能无法正确识别起始条件,导致总线挂死。
I2C 起始条件与停止条件时序图 起始条件 (S) SCL高时SDA下降 停止条件 (P) SCL高时SDA上升 SCL SDA VDD (高) VDD (高) SCL高时 SDA下降 SCL高时 SDA上升 数据位传输(SCL高电平时采样SDA) 起始条件后总线被占用,停止条件后总线释放。重复起始条件(Sr)用于改变传输方向。

1.4 数据传输格式

I2C数据传输以字节为单位,每个字节后跟随一个应答位(ACK/NACK)。完整的通信帧结构如下:

  1. 起始条件(S):主设备产生起始条件。
  2. 从设备地址(7位):主设备发送目标从设备地址。
  3. 读/写位(R/W):0表示写操作,1表示读操作。
  4. 应答位(ACK):从设备在第9个SCL周期拉低SDA表示应答。
  5. 数据字节(8位):主设备(写模式)或从设备(读模式)发送数据。
  6. 应答位(ACK):接收方在第9个SCL周期应答。
  7. 停止条件(P):主设备产生停止条件结束传输。
QNX驱动实现要点:在QNX I2C驱动中,i2c_send()和i2c_recv()函数内部自动处理起始条件、地址发送和停止条件。驱动开发者需要关注的是:
- 从设备地址的7位/10位模式配置
- 应答超时时间(通常设置为SCL周期的10倍)
- 重复起始条件的触发时机(在读写组合操作中)
I2C 完整通信帧结构(写操作示例) S 地址 (7位) R/W ACK 数据 (8位) ACK 数据 (8位) ACK P 帧结构说明: S=起始条件 | 地址=从设备7位地址 | R/W=0(写)/1(读) | ACK=从设备应答(低电平) | 数据=8位数据字节 | P=停止条件 读操作时,地址字节后主设备释放SDA控制权,从设备发送数据字节,主设备产生ACK或NACK。

1.5 总线仲裁与时钟同步

I2C总线支持多主设备通信,通过总线仲裁和时钟同步机制实现冲突避免:

  • 总线仲裁:多个主设备同时发送数据时,SDA上的低电平优先。发送高电平但检测到低电平的设备失去仲裁,转为从模式。
  • 时钟同步:多个主设备通过线与逻辑同步SCL时钟,所有设备同时拉低SCL,最慢的设备决定SCL低电平时间。
QNX多主场景:在QNX系统中,若多个I2C主控制器共享同一总线(如通过GPIO模拟),驱动必须实现仲裁超时检测。建议在驱动中设置I2C_ARBITRATION_TIMEOUT为10ms,避免总线死锁。

1.6 本章小结