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。
I2C总线物理连接拓扑图 Rₚ Rₚ VDD (1.8V / 3.3V) SCL(串行时钟线) SDA(串行数据线) RK SoC 主设备 (Master) Sensor A 从设备 (0x48) Sensor B 从设备 (0x4A) 说明:所有设备通过开漏输出挂接在SDA和SCL总线上, 外部上拉电阻Rₚ确保总线空闲时为高电平。

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等)控制传输方向和数据长度。但理解其时序对于调试逻辑分析仪波形至关重要。
I2C起始条件与停止条件时序图 SCL SDA 起始条件 (S) SCL=H, SDA↓ 停止条件 (P) SCL=H, SDA↑ 数据传输区域(地址 + 读写位 + 数据)

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位。
I2C完整数据帧结构图(写操作示例) S 起始 7-bit Addr 从设备地址 W 0 ACK 应答 Reg Addr 寄存器地址 ACK 应答 Data Byte 数据字节 ACK 应答 P 停止 I2C写操作帧结构说明 1. 主设备发送起始条件S,然后发送7位从设备地址 + 写标志W(0) 2. 从设备应答ACK后,主设备发送8位寄存器地址 3. 从设备再次应答ACK,主设备发送8位数据字节 4. 从设备应答ACK,主设备发送停止条件P结束传输

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位地址的传输分为两个阶段:

  1. 首字节:高5位固定为11110,后跟10位地址的高2位(A9:A8),最后1位为R/W标志。
  2. 次字节: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>),无需手动移位。但调试时通过逻辑分析仪抓取波形,必须理解地址字节的实际编码。
7位地址与10位地址传输格式对比 7位地址传输格式 S 7位地址 (A6:A0) 例: 1001000 (0x48) R/W 0/1 ACK 应答 10位地址传输格式 S 11110 A9 A8 首字节高5位+地址高2位 R/W 0/1 ACK 应答 A7 A6 A5 A4 A3 A2 A1 A0 次字节:地址低8位 ACK 应答 说明:7位地址仅需1字节传输地址+读写位;10位地址需要2字节,首字节高5位固定为11110。 RK平台Sensor驱动中99%以上使用7位地址,10位地址主要用于需要大量从设备的复杂系统。

2.5 I2C总线速率与RK平台适配

RK平台I2C控制器支持多种速率模式,驱动开发中需根据Sensor数据手册