1. I2C 总线基础:物理层协议、电气特性与通信机制
I2C(Inter-Integrated Circuit)总线由 Philips 公司(现 NXP)于 1980 年代推出,是一种同步、多主从、串行通信总线。在 Android 设备中,I2C 广泛用于连接传感器、触控芯片、电源管理 IC、音频编解码器等低速外设。理解 I2C 物理层与协议是驱动开发的第一道门槛。
1.1 物理层与电气特性
I2C 总线仅使用两条双向信号线:SCL(串行时钟线)和 SDA(串行数据线)。所有设备通过开漏输出(Open-Drain)连接到这两条线上,并通过上拉电阻接至 VDD(通常为 1.8V、3.3V 或 5V)。
| 参数 | 标准模式(100 kHz) | 快速模式(400 kHz) | 高速模式(3.4 MHz) |
|---|---|---|---|
| 最大时钟频率 | 100 kHz | 400 kHz | 3.4 MHz |
| 总线最大电容 | 400 pF | 400 pF | 100 pF |
| 上拉电阻典型值 | 4.7 kΩ | 2.2 kΩ | 1.0 kΩ |
| 逻辑低电平(VIL) | ≤ 0.3 × VDD | ≤ 0.3 × VDD | ≤ 0.3 × VDD |
| 逻辑高电平(VIH) | ≥ 0.7 × VDD | ≥ 0.7 × VDD | ≥ 0.7 × VDD |
1.2 起始条件(START)与停止条件(STOP)
I2C 总线在空闲时,SCL 和 SDA 均为高电平(由上拉电阻拉高)。总线上所有数据传输由主设备产生的起始条件和停止条件界定:
- 起始条件(S):SCL 为高电平时,SDA 从高电平切换到低电平。
- 停止条件(P):SCL 为高电平时,SDA 从低电平切换到高电平。
起始和停止条件由主设备独占产生,从设备只能检测这些条件。每次传输必须以起始条件开始,以停止条件结束,或者以重复起始条件(Sr)开始下一笔传输而不释放总线。
1.3 数据有效性
I2C 协议规定数据采样的严格时序:
- 数据稳定:在 SCL 时钟的高电平期间,SDA 上的数据必须保持稳定。
- 数据变化:仅在 SCL 为低电平时,SDA 上的数据才允许发生变化(起始条件和停止条件除外)。
每个数据字节传输 8 位(MSB 先发),之后跟随一个应答位(ACK/NACK)。主设备在 SCL 的第 9 个时钟周期释放 SDA,由从设备拉低 SDA 表示应答(ACK),或保持高电平表示非应答(NACK)。
1.4 应答机制(ACK/NACK)
应答机制是 I2C 总线可靠传输的核心。每次传输完 8 位数据后,接收方必须给出应答:
| 应答类型 | SDA 电平(第 9 个 SCL 周期) | 含义 | 典型场景 |
|---|---|---|---|
| ACK(应答) | 低电平 | 接收成功,可以继续发送下一字节 | 从设备正常接收数据或主设备正常读取数据 |
| NACK(非应答) | 高电平 | 接收失败或传输结束 | 从设备地址不匹配、寄存器不存在、主设备读操作结束 |
在 I2C 读操作中,主设备在读取最后一个字节后发送 NACK,以通知从设备停止发送,随后产生停止条件。
1.5 完整传输流程示例
以下是一个典型的 I2C 写寄存器操作流程(主设备向从设备写入 1 字节数据):
- 主设备产生起始条件(S)。
- 主设备发送7 位从设备地址 + 写位(0)(共 8 位)。
- 从设备在第 9 个 SCL 周期拉低 SDA 发送 ACK。
- 主设备发送寄存器地址(8 位)。
- 从设备发送 ACK。
- 主设备发送数据字节(8 位)。
- 从设备发送 ACK。
- 主设备产生停止条件(P)。
1.6 总线仲裁与多主设备
I2C 总线支持多主设备共享同一总线。当多个主设备同时尝试驱动总线时,通过线与(Wired-AND)特性进行仲裁:
- 如果某个主设备试图将 SDA 拉高,但检测到 SDA 实际为低电平(因为另一个主设备正在拉低),则该主设备失去仲裁并立即转为从模式。
- 仲裁过程不会丢失数据,也不会破坏通信。
在 Android 设备中,多主设备场景较少见,但部分电源管理芯片(如 PMIC)可能作为主设备主动上报中断,此时驱动需处理总线仲裁。
1.7 本章小结
| 知识点 | 核心要点 | 驱动开发关注点 |
|---|---|---|
| 电气特性 | 开漏输出 + 上拉电阻;SCL/SDA 双线 | DTS 中 clock-frequency 与上拉电阻匹配 |
| 起始/停止条件 | S 为 SCL 高时 SDA 下降沿;P 为 SCL 高时 SDA 上升沿 | 重复起始条件用于读写组合操作 |
| 数据有效性 | SCL 高电平时数据稳定;SCL 低电平时数据变化 | 时钟拉伸可能导致超时,需配置 adapter->timeout |
| 应答机制 | ACK = SDA 低;NACK = SDA 高 | NACK 通常表示地址错误或设备离线 |
| 总线仲裁 | 多主设备通过线与逻辑仲裁 | Android 中较少见,但 PMIC 主设备场景需注意 |