3. I2C 地址与寻址:7 位地址与 10 位地址格式、广播地址、保留地址、地址冲突解决

I2C 总线上的每个从设备都有一个唯一的地址,主设备通过发送目标地址来选择通信对象。理解地址格式、保留地址以及冲突解决机制,是设计多设备 I2C 系统的前提。本章将深入解析 7 位与 10 位地址结构、广播与保留地址的用途,并给出工程中地址冲突的排查与规避方法。

3.1 7 位地址格式

标准 I2C 通信使用 7 位地址,这是最广泛使用的寻址方式。地址在起始条件后作为第一个字节的高 7 位发送,最低位(LSB)为读写方向位(R/W)。

位序 7 (MSB) 6 5 4 3 2 1 0 (LSB)
内容 7 位从机地址 (A6–A0) R/W (0=写, 1=读)
  • 地址范围:0x00 – 0x7F(共 128 个地址),但其中 0x00–0x07 和 0x78–0x7F 为保留地址,实际可用地址约 112 个。
  • XMC 寄存器映射:在 XMC 的 I2C 模块中,7 位地址通过 I2C_MASTER->CFG 或 I2C_SLAVE->CFG 寄存器的 SLAVE_ADDR 位域配置。
  • 典型值:例如温度传感器 TMP102 的 7 位地址为 0x48(二进制 1001000)。
工程师提示: 数据手册中给出的地址通常是 7 位值。发送时需左移 1 位,并在 LSB 填入 R/W 位。例如地址 0x48 写操作时发送字节为 0x90(0x48 << 1 | 0)。

3.2 10 位地址格式

当系统中从设备数量超过 112 个,或需要与 7 位地址空间隔离时,可使用 10 位地址。10 位地址通过两个字节传输,第一个字节的前 5 位固定为 11110,作为 10 位地址标识。

字节 位 7 位 6 位 5 位 4 位 3 位 2 位 1 位 0
第 1 字节 1 1 1 1 0 地址位 A9–A8 R/W
第 2 字节 地址位 A7–A0
  • 地址范围:0x000 – 0x3FF(共 1024 个地址),与 7 位地址空间不重叠。
  • 兼容性:10 位地址主设备可以与 7 位地址从设备共存于同一总线,但 7 位地址从设备不会响应 11110 开头的地址。
  • XMC 支持:XMC4000 系列 I2C 模块支持 10 位地址模式,需在 I2C_SLAVE->CFG 中设置 ADDR_MODE 位为 1。
注意: 10 位地址的传输需要两个字节,通信效率略低于 7 位地址。在 XMC 项目中,除非从设备强制要求,否则优先使用 7 位地址以简化时序。

3.3 广播地址与保留地址

I2C 规范定义了一组特殊地址,用于总线管理和通用呼叫。这些地址不能被分配给普通从设备。

地址 (7 位) 名称 用途
0x00 广播地址 / 通用呼叫 主设备向所有从设备发送数据。从设备可选择是否响应。常用于系统复位或状态同步。
0x01 起始字节 用于慢速 MCU 检测总线起始条件,避免误判。
0x02 CBUS 地址 保留给 CBUS 兼容设备。
0x03–0x07 保留 未来扩展用途,不可分配。
0x78–0x7B 10 位地址标识 用于 10 位地址的第一个字节标识(11110xx)。
0x7C–0x7F 保留 测试与特殊模式,不可分配。
广播地址使用场景: 在 XMC 多设备系统中,主设备可通过广播地址 0x00 发送“软件复位”命令,所有支持通用呼叫的从设备同时复位,无需逐个寻址。

3.4 地址冲突解决

当多个从设备使用相同地址时,总线会出现地址冲突,导致通信紊乱。以下是常见的冲突原因与解决方案。

3.4.1 冲突原因

  • 相同型号器件:同一 PCB 上使用多片相同传感器(如两片 TMP102),其默认地址相同。
  • 地址引脚固定:部分器件地址引脚被直接接 VCC 或 GND,无法动态修改。
  • 地址空间耗尽:总线挂载设备超过可用地址数。

3.4.2 解决方案

方法 描述 适用场景
地址引脚重映射 利用器件 ADDR 引脚选择不同地址(如接 VCC、GND、SDA、SCL 组合)。 器件提供多个地址选项(如 PCA9548A 有 3 个地址引脚)。
I2C 多路复用器 使用 I2C 开关/多路复用器(如 TCA9548A)将总线分段,每段挂载相同地址器件。 大量同型号传感器需要独立访问。
软件地址分配 上电后通过 GPIO 或专用协议为从设备分配动态地址。 支持动态地址的智能传感器。
10 位地址扩展 将冲突设备切换至 10 位地址模式,扩大地址空间。 主从设备均支持 10 位地址。

3.4.3 XMC 调试技巧

  • 总线扫描:使用 XMC 的 I2C 主模式发送地址探测帧,记录所有 ACK 响应,快速发现重复地址。
  • 逻辑分析仪:捕获 SDA/SCL 波形,观察是否有两个从设备同时拉低 SDA 导致数据冲突。
  • 寄存器检查:读取 I2C_MASTER->STATUS 中的 ARB_LOST 位,判断是否因地址冲突导致仲裁丢失。
工程建议: 在原理图设计阶段,为每个 I2C 器件预留地址配置引脚的上拉/下拉电阻位。即使当前使用默认地址,也保留修改能力,避免 PCB 返工。

3.5 地址寻址流程 SVG 图

下图展示了主设备发送 7 位地址和 10 位地址的完整时序流程,以及从设备 ACK 响应机制。

I2C 地址寻址流程:7 位地址 vs 10 位地址 7 位地址寻址 1. 主设备发送起始条件 (S) 2. 发送第 1 字节: A6–A0 + R/W 3. 等待从设备 ACK (SDA 拉低) 4. 收到 ACK → 开始数据传输 5. 无 ACK → 发送停止条件 (P) 示例: 地址 0x48 写 → 发送 0x90 10 位地址寻址 1. 主设备发送起始条件 (S) 2. 发送第 1 字节: 11110 + A9–A8 + R/W 3. 等待从设备 ACK 4. 发送第 2 字节: A7–A0 5. 等待从设备 ACK 示例: 地址 0x1A3 写 → 0xF0 + 0xA3 地址冲突解决策略 • 硬件重映射:利用 ADDR 引脚选择不同地址组合 • I2C 多路复用器:使用 TCA9548A 等芯片分段隔离 • 软件分配:上电后通过 GPIO 或协议动态分配地址 ACK / NACK 响应规则 • ACK:从设备在第九个 SCL 时钟周期将 SDA 拉低,表示地址匹配成功 • NACK:从设备保持 SDA 高电平,表示地址无响应或设备忙

3.6 地址配置代码示例(XMC HAL)

以下代码展示如何在 XMC 的 I2C 从模式下配置 7 位地址和 10 位地址。

/* XMC I2C 从设备地址配置示例 */

/* 7 位地址配置:从设备地址 0x48 */
XMC_I2C_CH_SlaveConfig_t slave_config_7bit = {
    .address = 0x48,           /* 7 位地址值 */
    .address_mode = XMC_I2C_CH_ADDRESS_MODE_7_BIT,
    .enable_general_call = false
};
XMC_I2C_CH_Init(XMC_I2C0_CH1, &slave_config_7bit);

/* 10 位地址配置:从设备地址 0x01A3 */
XMC_I2C_CH_SlaveConfig_t slave_config_10bit = {
    .address = 0x01A3,         /* 10 位地址值 */
    .address_mode = XMC_I2C_CH_ADDRESS_MODE_10_BIT,
    .enable_general_call = false
};
XMC_I2C_CH_Init(XMC_I2C0_CH2, &slave_config_10bit);

/* 使能广播地址响应(可选) */
slave_config_7bit.enable_general_call = true;
XMC_I2C_CH_Init(XMC_I2C0_CH1, &slave_config_7bit);
关键检查点: 配置 10 位地址时,确保 address_mode 设置为 XMC_I2C_CH_ADDRESS_MODE_10_BIT,否则从设备会错误地将高两位解释为 7 位地址的一部分,导致通信失败。

3.7 本章小结

  • 7 位地址是 I2C 最常用的寻址方式,地址范围 0x00–0x7F,需避开保留地址。
  • 10 位地址通过两个字节传输,扩展地址空间至 1024 个,适用于大规模多设备系统。
  • 广播地址 0x00 用于全局命令,保留地址不可分配给普通从设备。
  • 地址冲突可通过硬件重映射、多路复用器、软件分配或 10 位地址扩展解决。
  • XMC HAL 库提供清晰的配置接口,支持 7 位/10 位地址和广播使能。