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米(取决于上拉电阻和线缆质量)。
2.2 起始条件与停止条件
I2C总线上每一次数据传输都由起始条件(START condition)开始,以停止条件(STOP condition)结束。这两个条件是总线通信的帧同步信号,具有唯一性,不会被误判为数据位。
| 条件 | 信号时序 | 说明 |
|---|---|---|
| 起始条件(S) | SCL为高电平时,SDA从高电平切换到低电平 | 主设备发起通信,所有从设备开始监听地址 |
| 停止条件(P) | SCL为高电平时,SDA从低电平切换到高电平 | 主设备结束通信,总线恢复空闲状态 |
| 重复起始条件(Sr) | 在未发送停止条件前,再次产生起始条件 | 用于改变数据传输方向或切换从设备,避免释放总线 |
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位地址的传输分为两个阶段:
- 第一个字节:高5位固定为
11110,接着是地址的A9和A8两位,最后是R/W位。 - 第二个字节:地址的低8位(A7:A0)。
| 特性 | 7位地址模式 | 10位地址模式 |
|---|---|---|
| 地址范围 | 0x00 ~ 0x7F | 0x000 ~ 0x3FF |
| 可用地址数 | 112(排除保留地址) | 1024 |
| 传输字节数 | 1字节(地址+R/W) | 2字节 |
| 兼容性 | 所有I2C设备均支持 | 仅支持10位地址的从设备 |
| Android BSP常见度 | 极高(95%以上传感器/外设) | 低(少数高端PMIC/编解码器) |
reg属性指定。对于7位地址,直接填写地址值(如reg = <0x48>);对于10位地址,需要设置I2C_CLIENT_TEN标志。内核的i2c_client结构体中的addr字段存储的是7位或10位的原始地址值。
2.4 数据传输格式
I2C的数据传输以字节为单位,每个字节后跟一个应答位(ACK/NACK)。完整的传输流程如下:
- 起始条件(S):主设备产生起始条件。
- 发送从设备地址:主设备发送7位或10位地址 + R/W位。
- 从设备应答(ACK):匹配地址的从设备在第9个SCL周期将SDA拉低,表示应答。
- 数据传输:每发送一个字节(8位),接收方在第9个SCL周期产生应答。
- 停止条件(P):主设备产生停止条件,结束传输。
2.4.1 写操作格式
主设备发送: S | 从设备地址(W) | ACK | 寄存器地址 | ACK | 数据字节1 | ACK | ... | 数据字节N | ACK | P
从设备响应: ACK ACK ACK ACK ACK