1. I2C协议基础:总线物理层与时序规范

I2C(Inter-Integrated Circuit)是一种由Philips(现NXP)开发的两线式串行通信协议,广泛应用于MCU与传感器、存储器、IO扩展器等外设之间的短距离通信。理解其物理层和时序是驱动开发的第一步。

1.1 总线物理层结构

I2C总线仅需两根双向信号线:

  • SCL(Serial Clock):串行时钟线,由主机(Master)驱动,用于同步数据传输。
  • SDA(Serial Data):串行数据线,用于双向传输地址和数据。

总线采用开漏(Open-Drain)输出结构,配合外部上拉电阻实现“线与”逻辑:

关键特性: 空闲时SCL和SDA均为高电平;任何设备拉低其中一条线即可发起操作。这种结构允许多主机仲裁,且无总线冲突风险。
参数 标准模式(100 kHz) 快速模式(400 kHz) 高速模式(3.4 MHz)
SCL最大频率 100 kHz 400 kHz 3.4 MHz
上拉电阻典型值 4.7 kΩ 2.2 kΩ 1.0 kΩ
总线电容上限 400 pF 400 pF 100 pF
最大从机数量 127(7位地址) 127 127
驱动开发提示: 在MCU的I2C外设初始化时,需根据总线负载电容和通信速率选择合适的上拉电阻。过小的电阻会增加功耗,过大的电阻会减慢上升沿,导致时序违规。

1.2 SCL/SDA时序规范

I2C协议对SCL和SDA的时序有严格定义,驱动开发中必须确保满足以下关键时间参数:

  • tHD;STA:起始条件保持时间(≥ 4.0 μs @ 100 kHz)
  • tSU;STA:重复起始条件建立时间(≥ 4.7 μs)
  • tHD;DAT:数据保持时间(≥ 0 ns)
  • tSU;DAT:数据建立时间(≥ 250 ns)
  • tLOW:SCL低电平时间(≥ 4.7 μs)
  • tHIGH:SCL高电平时间(≥ 4.0 μs)
  • tSU;STO:停止条件建立时间(≥ 4.0 μs)
  • tBUF:停止与起始条件间总线空闲时间(≥ 4.7 μs)
常见陷阱: 在轮询模式下,MCU主频较高时容易忽略SCL低电平时间tLOW。如果SCL高电平时间过短,从机可能无法正确采样SDA数据,导致通信失败。建议使用逻辑分析仪或示波器验证时序。

1.3 起始条件与停止条件

I2C总线上所有通信都以起始条件(START)开始,以停止条件(STOP)结束。这两个条件是总线状态转换的唯一合法边界。

起始条件(S)

当SCL为高电平时,SDA从高电平切换到低电平。此信号由主机产生,表示总线从空闲状态进入活跃状态。

停止条件(P)

当SCL为高电平时,SDA从低电平切换到高电平。此信号由主机产生,表示当前传输结束,总线恢复空闲。

重复起始条件(Sr)

在未产生停止条件的情况下,主机再次产生起始条件。常用于多字节读写或改变数据传输方向,无需释放总线。

I2C 起始条件与停止条件时序图 SCL SDA S SCL高时SDA↓ 地址/数据位(8位) P SCL高时SDA↑ 总线空闲:SCL=高,SDA=高 Sr 无P直接再S

1.4 完整数据传输流程

一次典型的I2C写操作包含以下步骤:

  1. 主机发送起始条件(S):SCL高时拉低SDA。
  2. 主机发送7位从机地址 + 读写位(R/W):地址高位在前,R/W=0表示写,1表示读。
  3. 从机发送应答位(ACK):从机在第9个SCL周期拉低SDA表示应答。
  4. 主机发送寄存器地址或数据字节:每字节后跟从机ACK。
  5. 主机发送停止条件(P):SCL高时释放SDA使其变高。
I2C 完整数据帧结构(7位地址写操作) S 从机地址 7位 R/W 1位 ACK 1位 数据字节 8位 ACK 1位 更多字节 可选 P 帧结构说明: • S(起始条件):SCL高时SDA下降沿 → 总线占用 • 从机地址 + R/W:主机指定通信对象和方向 • ACK/NACK:从机在第9个SCL周期应答(低=ACK,高=NACK) • P(停止条件):SCL高时SDA上升沿 → 总线释放

1.5 应答机制(ACK/NACK)

每个字节传输完成后,接收方必须在第9个SCL周期产生应答:

  • ACK(应答):接收方拉低SDA,表示准备接收下一字节。
  • NACK(非应答):接收方保持SDA高电平,表示传输结束或错误。
驱动开发要点: 在MCU的I2C中断服务函数中,检测到NACK时应立即停止后续传输并产生停止条件。轮询模式下,需在发送每字节后检查I2C状态寄存器的ACK标志位,避免死循环。

1.6 总结