3. 从设备地址概念
在I2C总线协议中,每个从设备必须拥有唯一的地址,主设备通过地址来选择通信目标。理解7位与10位地址格式、保留地址规则以及读写位的组合方式,是进行QNX I2C驱动适配与移植的基础。错误的地址配置会导致设备无法响应或总线冲突。
3.1 7位地址格式
7位地址是I2C协议中最常用的地址格式,占用总线帧的第1个字节的高7位(bit7~bit1),最低位(bit0)作为读写控制位(R/W)。
地址字节结构(7位模式):
Bit 7 (MSB) → Bit 1:从设备地址(A6~A0)
Bit 0 (LSB):R/W 位(0 = 写,1 = 读)
Bit 7 (MSB) → Bit 1:从设备地址(A6~A0)
Bit 0 (LSB):R/W 位(0 = 写,1 = 读)
例如,一个7位地址为 0x3C 的设备,在写操作时发送的地址字节为 0x78(0x3C << 1 | 0),读操作时为 0x79(0x3C << 1 | 1)。
3.2 10位地址格式
10位地址用于扩展I2C总线的寻址能力,允许连接更多从设备。10位地址的传输需要2个字节:第1个字节的高5位固定为 11110,后跟地址的高2位(A9~A8)和R/W位;第2个字节为地址的低8位(A7~A0)。
| 字节序号 | Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 |
|---|---|---|---|---|---|---|---|---|
| 第1字节 | 1 | 1 | 1 | 1 | 0 | A9 | A8 | R/W |
| 第2字节 | A7 | A6 | A5 | A4 | A3 | A2 | A1 | A0 |
| 7位地址(二进制) | 用途 | 说明 |
|---|---|---|
0000 000 |
通用呼叫地址 | 用于广播消息,所有支持通用呼叫的设备响应 |
0000 001 |
起始字节 | 用于慢速MCU检测总线起始 |
0000 010 |
CBUS地址 | 保留给CBUS兼容设备 |
0000 011 |
保留 | 未来扩展用途 |
0000 1xx |
HS模式主设备代码 | 高速模式(3.4MHz)主设备标识 |
1111 0xx |
10位地址前缀 | 10位地址第1字节的高5位 |
1111 1xx |
保留 | 未来扩展或设备ID |
移植调试警告: 在QNX BSP移植过程中,如果从设备地址落在保留地址范围内(如
0x00~0x07 或 0x78~0x7F),I2C控制器可能不会产生ACK响应,或者总线仲裁逻辑异常。务必查阅设备数据手册确认地址合法性。
3.4 地址与读写位组合
在I2C通信帧中,地址字节的R/W位决定了后续数据传输方向。主设备在发送起始条件后,首先发送地址字节,从设备通过地址匹配和R/W位判断是否参与通信。
地址字节组合示例(7位地址 0x3C):
- 写操作: 地址字节 = (0x3C << 1) | 0 = 0x78 → 主设备发送数据到从设备
- 读操作: 地址字节 = (0x3C << 1) | 1 = 0x79 → 从设备发送数据到主设备
在QNX I2C驱动中,地址与读写位的组合通常由底层库自动处理。开发者只需提供7位或10位原始地址,驱动会在发送时自动左移并添加R/W位。
/* QNX I2C 地址设置示例 */
i2c_addr_t addr;
/* 7位地址模式 */
addr.addr = 0x3C; /* 原始7位地址 */
addr.addr_type = I2C_ADDR_7BIT;
/* 10位地址模式 */
addr.addr = 0x02C3; /* 原始10位地址 */
addr.addr_type = I2C_ADDR_10BIT;
/* 发送写命令(驱动自动组合地址字节) */
i2c_send(handle, &addr, write_buf, len, I2C_STOP);
3.5 QNX驱动中的地址处理要点
- 地址左移规则: QNX I2C框架期望开发者提供原始7位或10位地址,驱动内部自动左移1位并添加R/W位。不要手动左移后传入。
- 10位地址标志: 使用10位地址时,必须在
i2c_send()或i2c_recv()的flags参数中设置I2C_ADDR_10BIT,否则驱动按7位地址解析。 - 地址冲突检测: 在BSP移植阶段,建议在初始化时扫描所有可能的从设备地址,确认没有地址冲突,特别是与保留地址重叠的情况。
- 设备树配置: 在QNX BSP的设备树(.dtsi)中,从设备地址通常以
reg = <0x3C>;形式指定,驱动解析时需注意字节序。
调试技巧: 使用QNX的
i2c-tools 或自定义测试程序,通过 i2c_detect 命令扫描总线,验证从设备地址是否正确响应。如果设备没有ACK,首先检查地址格式(7位 vs 10位)和R/W位组合。