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 表示读操作。
常见误区: 许多数据手册给出的地址是 7 位原始值(如 0x50),驱动配置时需左移 1 位。VxWorks 的 i2cLib 接口通常要求传入 7 位原始地址,库内部自动处理移位。
7 位寻址数据帧结构 S 7 位地址 R/W ACK 数据字节 ACK P S=起始条件,P=停止条件,ACK=从设备应答位。 7 位地址范围 0x00~0x7F,其中 0x00 为广播地址,0x01~0x03 为保留地址。

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。
10 位寻址数据帧结构 S 1111 0XX + R/W 高 5 位固定 11110 ACK 低 8 位地址 10 位地址 [7:0] ACK 数据... P 10 位地址编码规则: 第一字节高 5 位固定为 11110,紧接 2 位为地址高 2 位 (A9:A8),最低位为 R/W。 第二字节为地址低 8 位 (A7:A0)。 示例:10 位地址 0x2A3 → 第一字节 1111 010X (0xF4/0xF5),第二字节 0xA3。

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() 接口完成。地址配置需遵循以下步骤:

  1. 确定地址类型: 7 位或 10 位,根据从设备数据手册确认。
  2. 读取硬件引脚/寄存器: 许多 I2C 从设备通过外部引脚(如 AD0、AD1)或内部寄存器配置地址。
  3. 调用驱动接口: 传入 7 位原始地址(无需左移)。
  4. 验证地址唯一性: 同一 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 应答。
从设备地址配置与验证流程 读取数据手册 确定地址类型/引脚 调用 i2cDevCreate() 验证地址唯一性

3.5 地址配置常见故障与排查

故障现象 可能原因 排查方法
无 ACK 响应 地址错误、设备未上电、地址冲突 用示波器抓取 SDA 第 9 个时钟,检查 ACK 电平
通信偶尔失败 地址引脚虚焊、电平竞争 测量地址引脚电压,检查上拉电阻
10 位地址不识别 驱动未启用 10 位模式 确认 INCLUDE_I2C_10BIT_ADDR 已定义
广播命令无响应 从设备不支持广播 查阅数据手册确认广播支持位
调试技巧: 在 VxWorks shell 下使用 i2cProbe() 命令扫描总线上的所有设备地址,快速确认哪些地址有 ACK 响应。例如:i2cProbe "/i2c/0"。