2. I2C协议基础:物理层特性与通信机制

I2C(Inter-Integrated Circuit)总线是嵌入式系统中应用最广泛的板级同步串行通信协议之一,由Philips(现NXP)在1980年代发明。在Android内核的BSP开发中,I2C是连接主处理器与各类外设传感器、触摸屏、电源管理芯片、音频编解码器、NFC控制器等从设备的核心总线。理解I2C的物理层特性、信号时序与数据格式,是编写正确、健壮的I2C从设备驱动的必要前提。

2.1 I2C总线物理层特性(SDA/SCL)

I2C总线仅使用两条双向信号线完成所有通信:

  • SDA(Serial Data Line):串行数据线,用于传输地址和数据。
  • SCL(Serial Clock Line):串行时钟线,由主设备产生,同步所有数据传输。

两条线均通过上拉电阻(通常为4.7kΩ或10kΩ)连接到VDD(典型值为1.8V、3.3V或5V)。总线空闲时,SDA和SCL均为高电平。I2C采用开漏(Open-Drain)输出结构,任何设备都可以将总线拉低,但不能主动驱动为高电平。这种“线与”特性使得多主设备仲裁和时钟同步成为可能。

关键物理特性:
  • 双线制:SDA + SCL,节省PCB走线资源。
  • 开漏输出 + 上拉电阻:支持多设备挂接,无总线冲突风险。
  • 标准模式(100 kbit/s)、快速模式(400 kbit/s)、高速模式(3.4 Mbit/s)三种速率等级。
  • 总线电容限制:标准模式下最大总线电容约400 pF,对应最大总线长度约1米(取决于上拉电阻和线缆质量)。
Android BSP开发提示:在调试I2C通信问题时,首先使用示波器或逻辑分析仪检查SDA/SCL的上升沿时间是否满足规范。上升沿过缓通常意味着上拉电阻过大或总线电容过高,会导致通信失败或速率受限。
I2C总线物理连接拓扑 Rₚ Rₚ VDD SDA SCL 主设备 (AP/SoC) 从设备1 (传感器) 从设备2 (触摸屏) 开漏输出 + 上拉电阻 → 线与逻辑 任何设备均可拉低总线;空闲时总线自动恢复为高电平

2.2 起始条件与停止条件

I2C总线上每一次数据传输都由起始条件(START condition)开始,以停止条件(STOP condition)结束。这两个条件是总线通信的帧同步信号,具有唯一性,不会被误判为数据位。

条件 信号时序 说明
起始条件(S) SCL为高电平时,SDA从高电平切换到低电平 主设备发起通信,所有从设备开始监听地址
停止条件(P) SCL为高电平时,SDA从低电平切换到高电平 主设备结束通信,总线恢复空闲状态
重复起始条件(Sr) 在未发送停止条件前,再次产生起始条件 用于改变数据传输方向或切换从设备,避免释放总线
常见驱动错误:在中断上下文中调用I2C传输函数时,如果未正确管理起始/停止条件,可能导致总线挂死(SDA被从设备一直拉低)。务必确保每次传输以停止条件结束,或在需要时使用重复起始条件。
起始条件与停止条件时序 SCL SDA S 起始条件 P 停止条件 SCL高电平时,SDA的下降沿→起始;上升沿→停止

2.3 7位地址模式与10位地址模式

I2C总线上的每个从设备都有一个唯一的地址,主设备通过地址选择要通信的目标。I2C规范定义了两种地址长度:

2.3.1 7位地址模式

7位地址是I2C最常用的地址模式,地址范围为0x00 ~ 0x7F(共128个地址),其中0x00为通用呼叫地址,0x01~0x07为保留地址,实际可用地址约112个。在数据传输时,7位地址左移1位,最低位作为读写标志位(R/W):

  • R/W = 0:主设备写数据到从设备
  • R/W = 1:主设备从从设备读数据

因此,在总线传输的字节中,地址字节的格式为:[A6:A0][R/W],其中A6为最高位。

2.3.2 10位地址模式

当系统中从设备数量超过112个时,可使用10位地址模式。10位地址的传输分为两个阶段:

  1. 第一个字节:高5位固定为11110,接着是地址的A9和A8两位,最后是R/W位。
  2. 第二个字节:地址的低8位(A7:A0)。
特性 7位地址模式 10位地址模式
地址范围 0x00 ~ 0x7F 0x000 ~ 0x3FF
可用地址数 112(排除保留地址) 1024
传输字节数 1字节(地址+R/W) 2字节
兼容性 所有I2C设备均支持 仅支持10位地址的从设备
Android BSP常见度 极高(95%以上传感器/外设) 低(少数高端PMIC/编解码器)
驱动开发提示:在Linux内核中,I2C从设备地址通过设备树(Device Tree)的reg属性指定。对于7位地址,直接填写地址值(如reg = <0x48>);对于10位地址,需要设置I2C_CLIENT_TEN标志。内核的i2c_client结构体中的addr字段存储的是7位或10位的原始地址值。
7位地址与10位地址格式对比 7位地址格式: A6 A5 A4 A3 A2 A1 A0 R/W ← 7位地址 → 10位地址格式(第一字节): 1 1 1 1 0 A9 A8 R/W 10位地址格式(第二字节): A7 A6 A5 A4 A3 A2 A1 A0 ← 低8位地址 →

2.4 数据传输格式

I2C的数据传输以字节为单位,每个字节后跟一个应答位(ACK/NACK)。完整的传输流程如下:

  1. 起始条件(S):主设备产生起始条件。
  2. 发送从设备地址:主设备发送7位或10位地址 + R/W位。
  3. 从设备应答(ACK):匹配地址的从设备在第9个SCL周期将SDA拉低,表示应答。
  4. 数据传输:每发送一个字节(8位),接收方在第9个SCL周期产生应答。
  5. 停止条件(P):主设备产生停止条件,结束传输。

2.4.1 写操作格式

主设备发送: S | 从设备地址(W) | ACK | 寄存器地址 | ACK | 数据字节1 | ACK | ... | 数据字节N | ACK | P
从设备响应:         ACK           ACK           ACK               ACK               ACK

2