3. I2C 寻址机制:7位寻址、10位寻址、广播地址、保留地址、从设备地址配置
I2C 总线采用主从架构,所有通信均由主设备发起,从设备通过唯一的地址响应。理解寻址机制是配置驱动和排查设备冲突的基础。本章详细解析 7 位寻址、10 位寻址、广播地址、保留地址以及 VxWorks 下的从设备地址配置方法。
3.1 7 位寻址
标准 I2C 总线使用 7 位从设备地址,地址范围 0x00 ~ 0x7F(共 128 个)。主设备在起始条件后发送的第一个字节包含:7 位地址(高 7 位)+ 读/写位(最低位)。
关键公式: 第一字节 = (从设备地址 << 1) | R/W
R/W = 0 表示写操作,R/W = 1 表示读操作。
R/W = 0 表示写操作,R/W = 1 表示读操作。
常见误区: 许多数据手册给出的地址是 7 位原始值(如 0x50),驱动配置时需左移 1 位。VxWorks 的 i2cLib 接口通常要求传入 7 位原始地址,库内部自动处理移位。
3.2 10 位寻址
当系统中从设备数量超过 128 个时,I2C 规范定义了 10 位寻址模式。主设备通过发送两个字节来指定 10 位地址:
- 第一字节: 1111 0XX + R/W,其中高 5 位固定为 11110,XX 为 10 位地址的高 2 位。
- 第二字节: 10 位地址的低 8 位。
| 地址类型 | 第一字节(二进制) | 地址范围 | 最大设备数 |
|---|---|---|---|
| 7 位寻址 | AAAA AAAX | 0x00 ~ 0x7F | 128 |
| 10 位寻址 | 1111 0XX + 低 8 位 | 0x000 ~ 0x3FF | 1024 |
兼容性注意: 10 位寻址需要主设备和从设备都支持该模式。VxWorks 的 i2cCore 驱动默认支持 7 位寻址,启用 10 位寻址需在 BSP 配置中定义 INCLUDE_I2C_10BIT_ADDR。
3.3 广播地址与保留地址
I2C 规范保留了一些特殊地址用于系统管理:
| 地址(7 位) | 名称 | 用途 | 响应要求 |
|---|---|---|---|
| 0x00 | 广播地址 | 主设备向所有从设备发送通用呼叫 | 支持广播的从设备必须 ACK |
| 0x01 | 起始字节 | 用于慢速 MCU 检测总线起始 | 从设备忽略 |
| 0x02 | CBUS 地址 | 保留给 CBUS 兼容设备 | 标准 I2C 设备忽略 |
| 0x03 | 保留 | 未来扩展用途 | 必须忽略 |
| 0x04 ~ 0x07 | 高速模式地址 | Hs 模式主设备标识 | 高速从设备识别 |
| 0x78 ~ 0x7B | 10 位地址前缀 | 10 位寻址第一字节范围 | 支持 10 位寻址的设备 |
广播地址使用场景: 系统复位后,主设备可通过广播地址 (0x00) 发送“通用呼叫”命令,通知所有从设备进入特定状态。VxWorks 驱动中可通过 i2cMasterSend() 直接发送地址 0x00 实现。
3.4 从设备地址配置
在 VxWorks 中配置 I2C 从设备地址通常通过 i2cDevCreate() 或 i2cSlaveCreate() 接口完成。地址配置需遵循以下步骤:
- 确定地址类型: 7 位或 10 位,根据从设备数据手册确认。
- 读取硬件引脚/寄存器: 许多 I2C 从设备通过外部引脚(如 AD0、AD1)或内部寄存器配置地址。
- 调用驱动接口: 传入 7 位原始地址(无需左移)。
- 验证地址唯一性: 同一 I2C 总线上不允许两个从设备使用相同地址。
/* VxWorks I2C 从设备地址配置示例 */
#include <i2cLib.h>
I2C_DEV *pDev;
UINT8 slaveAddr = 0x50; /* 7 位原始地址,例如 EEPROM AT24C02 */
/* 创建 I2C 从设备对象 */
pDev = i2cDevCreate("/i2c/0", slaveAddr, I2C_ADDR_TYPE_7BIT);
if (pDev == NULL)
{
printf("i2cDevCreate failed, errno = 0x%x\n", errno);
return ERROR;
}
/* 配置传输速率(标准模式 100kHz) */
i2cDevSet(pDev, I2C_DEV_SPEED, I2C_SPEED_STANDARD);
/* 执行写操作 */
UINT8 writeData[] = {0x00, 0xAB};
STATUS status = i2cDevWrite(pDev, writeData, sizeof(writeData));
if (status != OK)
{
printf("I2C write failed\n");
}
地址冲突排查: 若总线上多个设备地址相同,会导致 ACK 冲突和通信失败。使用示波器或逻辑分析仪抓取起始条件后的地址字节,确认是否有多个从设备同时拉低 SDA 应答。
3.5 地址配置常见故障与排查
| 故障现象 | 可能原因 | 排查方法 |
|---|---|---|
| 无 ACK 响应 | 地址错误、设备未上电、地址冲突 | 用示波器抓取 SDA 第 9 个时钟,检查 ACK 电平 |
| 通信偶尔失败 | 地址引脚虚焊、电平竞争 | 测量地址引脚电压,检查上拉电阻 |
| 10 位地址不识别 | 驱动未启用 10 位模式 | 确认 INCLUDE_I2C_10BIT_ADDR 已定义 |
| 广播命令无响应 | 从设备不支持广播 | 查阅数据手册确认广播支持位 |
调试技巧: 在 VxWorks shell 下使用
i2cProbe() 命令扫描总线上的所有设备地址,快速确认哪些地址有 ACK 响应。例如:i2cProbe "/i2c/0"。