3. I2C地址机制:7位地址与10位地址格式、地址分配规则、保留地址

在RK平台Sensor驱动开发中,I2C地址是主机与从设备通信的唯一标识。理解7位与10位地址格式、地址分配规则以及保留地址,是正确配置设备树和驱动代码的基础。本章将系统梳理I2C地址机制的核心知识点。

3.1 7位地址格式

7位地址是I2C总线最常用的地址格式,地址范围从0x00到0x7F(共128个地址)。在数据传输时,7位地址被左移1位,最低位作为读写标志位(R/W)。

关键点: 7位地址在总线上的实际传输格式为:地址[6:0] + R/W位。例如,设备地址0x50在写操作时发送0xA0,读操作时发送0xA1。
7位I2C地址传输格式 S 地址[6:0] (7位) R/W ACK 数据字节 P 示例:设备地址0x50 → 总线发送0xA0(写)或0xA1(读) S = 起始条件,P = 停止条件,ACK = 从设备应答

3.2 10位地址格式

10位地址用于扩展I2C地址空间,地址范围从0x000到0x3FF(共1024个地址)。10位地址的传输分为两个阶段:第一个字节包含11110xx作为前缀,第二个字节为地址的低8位。

10位I2C地址传输格式 S 11110 A9 A8 R/W ACK A7 A6 A5 A4 A3 A2 A1 A0 ACK 数据... P 第一字节:11110 + A9 + A8 + R/W(A9和A8是10位地址的最高两位) 第二字节:A7 ~ A0(10位地址的低8位) 示例:10位地址0x2A3 → 第一字节:11110 10 0(写)= 0xF2,第二字节:0xA3 注意:10位地址的从设备在应答时,两个字节都需要ACK

3.3 地址分配规则

I2C地址分配遵循以下核心规则,在RK平台驱动开发中必须严格遵守:

  • 唯一性: 同一I2C总线上每个从设备必须拥有唯一的地址,地址冲突会导致通信失败。
  • 硬件配置: 大多数Sensor通过引脚电平(ADDR、SA0等)配置地址,驱动开发时需要根据硬件原理图确定实际地址。
  • 设备树配置: 在RK平台设备树中,通过reg属性指定7位地址值,驱动通过i2c_client->addr获取。
  • 地址偏移: 部分设备手册给出的地址包含R/W位(8位格式),驱动开发时需转换为7位格式。
RK平台实践提示: 在RK设备树中,I2C地址统一使用7位格式。例如:reg = <0x50>; 表示设备地址为0x50。如果手册给出的是0xA0(8位写地址),则实际7位地址为0x50。

3.4 保留地址

I2C规范定义了一系列保留地址,这些地址不能分配给普通从设备。以下是完整的保留地址表:

地址类型 地址范围 可用地址数 总线传输字节数 典型应用
7位地址 0x00 ~ 0x7F 112(除去保留地址) 1字节(地址+R/W) 大多数Sensor、EEPROM、ADC
10位地址 0x000 ~ 0x3FF 1024 2字节(前缀+低8位) 复杂传感器集线器、多通道设备
地址(7位) 用途 说明
0x00 通用呼叫地址 用于广播消息,所有设备都应应答
0x01 起始字节 用于慢速设备检测总线
0x02 CBUS地址 保留给CBUS兼容设备
0x03 保留 未来扩展用途
0x04 ~ 0x07 高速模式主设备码 用于高速模式(Hs-mode)
0x78 ~ 0x7B 10位地址后缀 用于10位地址的从设备响应
0x7C ~ 0x7F 保留 未来扩展用途
I2C 7位地址空间分配图 保留地址 0x00 ~ 0x07 可用地址(普通从设备) 0x08 ~ 0x77(共112个地址) 保留地址 0x78 ~ 0x7F 保留地址详细说明 • 0x00:通用呼叫地址,用于主机向所有从设备广播消息 • 0x01:起始字节,用于慢速设备识别总线活动 • 0x04~0x07:高速模式主设备码,用于Hs-mode传输 • 0x78~0x7B:10位地址后缀,用于10位地址从设备的响应 • 0x7C~0x7F:保留给未来扩展,不可用于普通设备

3.5 RK平台地址配置实践

在RK平台Sensor驱动开发中,I2C地址配置涉及以下关键步骤:

  1. 确认硬件地址: 查看原理图,确认Sensor的ADDR引脚电平,确定实际7位地址。
  2. 设备树配置: 在设备树中填写正确的reg属性值。
  3. 驱动匹配: 驱动中通过i2c_device_id或of_match_table匹配设备。
  4. 地址验证: 使用i2cdetect工具扫描总线,验证地址是否正确。
常见错误: 部分开发者将8位地址(含R/W位)直接写入设备树,导致驱动无法匹配设备。例如,手册写地址0xDE(8位),实际7位地址应为0x6F。务必确认设备树使用7位格式。
// RK平台设备树I2C地址配置示例
&i2c1 {
    status = "okay";
    clock-frequency = <400000>;  // 400kHz标准模式
    
    // 7位地址传感器
    sensor_a: sensor-a@50 {
        compatible = "vendor,sensor-a";
        reg = <0x50>;           // 7位地址:0x50
        interrupt-parent = <&gpio1>;
        interrupts = <RK_PB5 IRQ_TYPE_LEVEL_LOW>;
    };
    
    // 10位地址传感器(较少见)
    sensor_b: sensor-b@2a3 {
        compatible = "vendor,sensor-b";
        reg = <0x2a3>;          // 10位地址:0x2A3
        // 注意:RK平台设备树reg属性自动识别7位/10位地址
    };
};
驱动开发要点: 在RK平台驱动中,通过i2c_client->addr获取设备地址,无需手动转换。驱动应使用i2c_smbus_read/write系列函数进行寄存器读写,这些函数会自动处理地址格式。