2. I2C协议基础:I2C总线物理层、起始/停止条件、数据帧格式、7位与10位地址
在RK平台Sensor驱动开发中,I2C(Inter-Integrated Circuit)总线是连接主控SoC与Sensor芯片最常用的串行通信接口。理解I2C协议的物理层特性、时序信号、数据帧结构以及地址映射机制,是正确配置Sensor寄存器、实现可靠数据读写的前提。本节将从物理层到协议层,系统梳理I2C的核心知识点。
2.1 I2C总线物理层
I2C总线采用两线制(Two-Wire)串行总线架构,仅需SDA(串行数据线)和SCL(串行时钟线)两根信号线即可完成双向数据传输。总线上的每个设备都通过唯一的地址进行识别,主设备(Master)负责产生时钟信号并发起通信,从设备(Slave)响应主设备的请求。
物理层关键特性:
- 开漏输出(Open-Drain):SDA和SCL均为开漏结构,必须外接上拉电阻(通常为4.7kΩ或10kΩ)至VDD(1.8V/3.3V/5V)。
- 线与逻辑(Wired-AND):多个设备可共享总线,任一设备拉低电平即总线为低;所有设备释放(高阻)时总线被上拉至高电平。
- 双向传输:SDA和SCL均为双向信号线,主设备与从设备通过分时驱动SDA完成数据交换。
- 多主设备支持:多个主设备可挂载在同一总线上,通过仲裁机制(Arbitration)决定总线控制权。
- 标准速率:标准模式(100 kbit/s)、快速模式(400 kbit/s)、高速模式(3.4 Mbit/s)。RK平台Sensor驱动通常使用100kHz或400kHz。
2.2 起始条件与停止条件
I2C总线的数据传输由起始条件(START Condition)和停止条件(STOP Condition)界定。这两个条件是总线通信的“帧头”和“帧尾”,由主设备在SCL为高电平时控制SDA的电平跳变产生。
| 条件类型 | 信号时序定义 | 方向 | 说明 |
|---|---|---|---|
| 起始条件 (S) | SCL = H,SDA 从 H → L | 主设备→总线 | 通知所有从设备:总线即将开始传输 |
| 停止条件 (P) | SCL = H,SDA 从 L → H | 主设备→总线 | 通知所有从设备:总线传输结束,释放总线 |
| 重复起始条件 (Sr) | 在无停止条件的情况下再次产生S | 主设备→总线 | 用于组合读写(如写寄存器地址后立即读数据) |
驱动开发注意:在RK平台Sensor驱动中,起始条件和停止条件的时序由I2C控制器硬件自动产生,驱动层只需通过寄存器配置(如I2C_CON、I2C_MRXADDR等)控制传输方向和数据长度。但理解其时序对于调试逻辑分析仪波形至关重要。
2.3 数据帧格式
I2C的数据传输以字节(Byte)为单位,每个字节后跟随一个应答位(ACK/NACK)。完整的I2C数据帧包含:起始条件、从设备地址、读写标志、数据字节、应答位以及停止条件。
2.3.1 单字节写操作帧格式
| S | 7-bit Slave Address | W (0) | ACK | 8-bit Register Address | ACK | 8-bit Data | ACK | P |
2.3.2 单字节读操作帧格式
| S | 7-bit Slave Address | W (0) | ACK | 8-bit Register Address | ACK | Sr | 7-bit Slave Address | R (1) | ACK | 8-bit Data | NACK | P |
帧格式关键点:
- 地址字节:由7位从设备地址 + 1位读写标志(R/W)组成。R/W=0表示写,R/W=1表示读。
- 应答位(ACK):接收方在每字节的第9个SCL周期将SDA拉低表示应答;若接收方未应答(NACK),主设备应发送停止条件终止传输。
- 重复起始(Sr):在读操作中,主设备在写完寄存器地址后,不发送停止条件,而是再次发送起始条件,然后发送从设备地址+读标志,实现“先写后读”的组合传输。
- 数据字节:MSB(最高位)优先传输,每个字节8位。
2.4 7位地址与10位地址
I2C协议支持两种从设备地址格式:7位地址和10位地址。RK平台Sensor驱动中绝大多数Sensor使用7位地址,但了解10位地址的扩展机制有助于处理特殊场景。
| 特性 | 7位地址 | 10位地址 |
|---|---|---|
| 地址范围 | 0x00 ~ 0x7F(128个地址,保留16个) | 0x000 ~ 0x3FF(1024个地址) |
| 有效地址数 | 112个(0x08 ~ 0x77) | 1024个 |
| 首字节格式 | 7位地址 + R/W位 | 11110 + 地址高2位 + R/W位 |
| 传输字节数 | 1字节(地址+读写位) | 2字节(首字节+次字节8位地址) |
| 兼容性 | 所有I2C设备均支持 | 仅支持10位地址的设备 |
| RK Sensor常用 | 是(如0x48、0x4A、0x6C等) | 极少使用 |
2.4.1 7位地址映射规则
在I2C协议中,7位地址在传输时被左移1位,最低位填充R/W标志。例如,Sensor设备地址为0x48(二进制:1001000),在写操作时发送的地址字节为0x90(10010000),读操作时为0x91(10010001)。
地址映射示例:
Sensor 7位地址: 0x48 (二进制: 1001000)
写操作地址字节: 0x48 << 1 | 0 = 0x90 (二进制: 10010000)
读操作地址字节: 0x48 << 1 | 1 = 0x91 (二进制: 10010001)
2.4.2 10位地址传输格式
10位地址的传输分为两个阶段:
- 首字节:高5位固定为11110,后跟10位地址的高2位(A9:A8),最后1位为R/W标志。
- 次字节:10位地址的低8位(A7:A0)。
首字节: [1 1 1 1 0 A9 A8 R/W]
次字节: [A7 A6 A5 A4 A3 A2 A1 A0]
驱动开发提示:在RK平台Linux内核I2C子系统中,地址通过
struct i2c_client的addr字段传递,内核会自动处理7位/10位地址的编码。驱动开发者只需在设备树或板级文件中指定正确的从设备地址(如reg = <0x48>),无需手动移位。但调试时通过逻辑分析仪抓取波形,必须理解地址字节的实际编码。
2.5 I2C总线速率与RK平台适配
RK平台I2C控制器支持多种速率模式,驱动开发中需根据Sensor数据手册