2. I2C 通信时序详解:起始条件、停止条件、数据有效性、应答信号(ACK/NACK)

I2C(Inter-Integrated Circuit)总线是一种由飞利浦公司开发的两线式串行总线,广泛应用于连接微控制器及其外围设备。理解其通信时序是驱动开发的基础。本章将深入解析 I2C 总线上的四个核心时序要素:起始条件、停止条件、数据有效性以及应答机制。

2.1 I2C 总线物理层与信号线

I2C 总线仅使用两条双向开漏信号线:

  • SCL(Serial Clock Line):串行时钟线,由主设备产生,用于同步数据传输。
  • SDA(Serial Data Line):串行数据线,用于在主设备和从设备之间传输地址和数据。
关键概念:由于 SCL 和 SDA 是开漏输出,总线空闲时,两条线均通过上拉电阻被拉至高电平(Vdd)。任何设备都可以通过将线拉低来发起通信或应答。
I2C 总线物理连接示意图 主设备 (Master) 从设备 1 (Slave) 从设备 2 (Slave) Rp Rp SDA SCL

2.2 起始条件(START Condition)与停止条件(STOP Condition)

I2C 总线的数据传输由起始条件开始,由停止条件结束。这两个条件是总线状态变化的特殊序列,由主设备产生。

2.2.1 起始条件(S)

当 SCL 线处于高电平时,SDA 线从高电平切换到低电平,表示一个起始条件。此信号告诉总线上的所有从设备,主设备即将开始一次新的数据传输。

2.2.2 停止条件(P)

当 SCL 线处于高电平时,SDA 线从低电平切换到高电平,表示一个停止条件。此信号标志着本次数据传输的结束,总线恢复空闲状态。

起始条件 (S) 与 停止条件 (P) 时序 SCL SDA 起始条件 (S) SDA 下降沿,SCL 高 停止条件 (P) SDA 上升沿,SCL 高 总线空闲状态:SCL 和 SDA 均为高电平
驱动开发要点:在编写 I2C 控制器驱动时,起始和停止条件的产生通常由硬件 I2C 控制器自动完成。但在软件模拟 I2C(Bit-Bang)模式下,驱动开发者必须严格按照时序要求,通过 GPIO 精确控制 SCL 和 SDA 的电平变化。

2.3 数据有效性(Data Validity)

I2C 协议规定,在时钟线 SCL 为高电平期间,数据线 SDA 上的电平必须保持稳定。只有在 SCL 为低电平时,SDA 上的电平才允许发生变化。这意味着数据采样发生在 SCL 的上升沿或高电平期间。

  • 数据采样:接收方在 SCL 的上升沿或高电平期间读取 SDA 上的电平。
  • 数据变化:发送方必须在 SCL 为低电平时更新 SDA 上的数据,以确保数据在 SCL 高电平时稳定。
数据有效性:SCL 高电平时 SDA 稳定 SCL SDA D7 D6 D5 D4 采样点 采样点 采样点 采样点 数据变化只能在 SCL 低电平时发生

2.4 应答信号(ACK/NACK)

I2C 总线上的每个数据字节(8 位)后都必须跟随一个应答位。应答位由接收方产生,用于向发送方确认数据是否成功接收。

2.4.1 应答机制

  • ACK(Acknowledge,应答):在第 9 个时钟周期,接收方将 SDA 线拉低,表示“已成功接收数据,请继续发送”。
  • NACK(Not Acknowledge,非应答):在第 9 个时钟周期,接收方保持 SDA 线为高电平,表示“未成功接收数据”或“传输结束”。

2.4.2 应答信号的作用

场景 发送方 接收方 应答位 含义
主设备发送地址 主设备 从设备 ACK 从设备地址匹配,准备通信
主设备发送数据 主设备 从设备 ACK 从设备已接收数据,可以继续发送
主设备发送数据 主设备 从设备 NACK 从设备无法接收更多数据(如缓冲区满)
主设备接收数据 从设备 主设备 ACK 主设备已接收数据,请继续发送
主设备接收数据 从设备 主设备 NACK 主设备通知从设备停止发送(传输结束)
应答信号 (ACK/NACK) 时序 SCL SDA 8 位数据字节 (由发送方驱动) ACK (SDA 低) 1 2 ... 8 9 第 9 个时钟周期:接收方将 SDA 拉低表示 ACK,保持高表示 NACK NACK 场景:从设备忙、地址未匹配或主设备要求停止传输
常见驱动 Bug:在中断驱动的 I2C 传输中,如果主设备在接收最后一个字节后未发送 NACK,从设备会继续发送数据,导致总线挂死。务必在接收完所需数据后,在第 9 个时钟周期释放 SDA(即发送 NACK)。

2.5 完整数据传输流程

一个完整的 I2C 数据传输流程如下:

  1. 起始条件(S):主设备产生起始条件。
  2. 发送从设备地址(7 位或 10 位):主设备发送从设备地址,后跟读写位(R/W)。
  3. 从设备应答(ACK):地址匹配的从设备发送 ACK。
  4. 数据传输:主设备(写模式)或从设备(读模式)发送数据字节,每字节后跟随一个应答位。
  5. 停止条件(P):主设备产生停止条件,结束通信。
完整 I2C 数据传输流程 起始条件 (S) 地址 + R/W 位 从设备 ACK 数据字节 停止条件 (P) 数据字节可重复多次,每次后跟 ACK/NACK 主设备在接收完最后一个字节后发送 NACK,然后产生停止条件

2.6 时序参数与高速模式

I2C 总线支持多种工作模式,不同模式下的时序参数有所不同。下表列出了标准模式和快速模式的关键时序参数:

参数 符号 标准模式 (100 kHz) 快速模式 (400 kHz) 说明
SCL 时钟频率 f_SCL 100 kHz 400 kHz 最大时钟频率
保持时间(起始条件) t_HD;STA 4.0 μs 0.6 μs 起始条件后 SCL 低电平保持时间
建立时间(停止条件) t_SU;STO 4.0 μs 0.6 μs 停止条件前 SCL 高电平建立时间
数据保持时间 t_HD;DAT 0 μs 0 μs SCL 低电平后 SDA 数据保持时间
数据建立时间 t_SU;DAT 250 ns 100 ns SCL 高电平前 SDA 数据建立时间
SCL 低电平时间 t_LOW 4.7 μs 1.3 μs SCL 低电平最小周期
SCL 高电平时间 t_HIGH 4.0 μs 0.6 μs SCL 高电平最小周期
驱动优化提示:在 Linux 内核中,I2C 控制器驱动通过配置时钟分频寄存器来设置 SCL 频率。对于高速传感器(如 3D 加速度计),建议使用快速模式(400 kHz)以提高数据吞吐量,但需确保总线电容和上拉电阻满足快速模式的时序要求。

2.7 本章小结

  • 起始/停止条件:由主设备在 SCL 高电平时改变 SDA 电平产生,是通信的开始和结束标志。
  • 数据有效性:数据在 SCL 高电平时被采样,在 SCL 低电平时变化。
  • 应答信号:第 9 个时钟周期,接收方拉低 SDA 为 ACK,保持高为 NACK,是流量控制和错误检测的关键。
  • 时序参数:不同工作模式(标准/快速/高速)有严格的时序要求,驱动开发时必须确保满足这些参数。