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

I2C总线上的每个从机设备都必须拥有一个唯一的地址,主设备通过地址来选择与之通信的从机。I2C协议定义了两种地址格式:7位地址和10位地址。理解地址格式、分配规则以及保留地址的含义,是正确配置从机设备寄存器的基础。

3.1 7位地址格式

7位地址是I2C协议中最常用、最基础的地址格式。在7位地址模式下,地址占用一个字节的高7位,最低位(LSB)作为读写控制位(R/W)。

  • 地址字节结构:A6 A5 A4 A3 A2 A1 A0 R/W。其中A6~A0为7位从机地址,R/W为0表示写操作,为1表示读操作。
  • 地址范围:从0x00到0x7F(共128个地址),但并非所有地址都可用于普通设备。
  • 传输顺序:主设备在发送起始条件后,先发送地址字节(高7位地址 + R/W位),然后等待从机应答。
MCU驱动要点:在配置I2C从机地址寄存器时,通常需要将7位地址左移1位,空出最低位作为R/W位。例如,从机地址为0x32,则地址寄存器应写入0x64(即0x32 << 1)。

3.2 10位地址格式

当系统中从机设备数量超过128个,或需要兼容更多设备时,I2C协议引入了10位地址格式。10位地址的传输需要两个字节:第一个字节的前5位为保留标识11110,后2位为10位地址的高2位;第二个字节为10位地址的低8位。

传输阶段 字节内容 说明
第1字节(高7位) 11110 A9 A8 R/W 前5位固定为11110,A9 A8为地址高2位,R/W为读写位
第2字节(低8位) A7 A6 A5 A4 A3 A2 A1 A0 10位地址的低8位
  • 地址范围:0x000 ~ 0x3FF(共1024个地址)。
  • 兼容性:10位地址与7位地址在总线上可以共存,但主设备和从设备都必须支持10位地址模式。
  • 应答时序:主设备发送完第一个字节后,从机需应答;发送完第二个字节后,从机再次应答。
实战建议:在嵌入式MCU驱动开发中,绝大多数传感器、EEPROM、ADC等外设都使用7位地址。10位地址多见于高端音频编解码器、视频处理芯片等复杂设备。除非芯片手册明确要求,否则优先使用7位地址以简化驱动逻辑。

3.3 地址分配规则与保留地址

I2C总线规范对地址空间进行了严格划分,部分地址被保留用于特殊功能,普通设备不得使用。下表列出了关键的保留地址区域:

地址范围(7位) 用途 说明
0x00 广播地址 / 通用呼叫地址 主设备发送此地址时,所有从机都应应答(如果支持广播)
0x01 ~ 0x03 保留 用于未来扩展或特殊总线协议
0x04 ~ 0x07 高速模式(Hs-mode)保留 用于高速模式下的主设备标识
0x78 ~ 0x7B 10位地址标识 前5位为11110,用于10位地址扩展
0x7C ~ 0x7F 保留 用于特殊协议或测试模式

地址分配规则总结:

  • 普通设备地址:7位地址中,0x08 ~ 0x77(共112个地址)可供普通从机设备使用。
  • 地址冲突避免:同一I2C总线上,每个从机地址必须唯一。MCU驱动初始化时,应检查从机地址是否在可用范围内。
  • 可编程地址:多数I2C从机芯片通过引脚(如A0、A1、A2)或寄存器配置来设定地址,驱动开发者需根据硬件连接确定最终地址。
常见错误:初学者容易将0x00(广播地址)误用作普通从机地址,导致总线上所有设备同时响应,造成数据冲突。务必在驱动初始化时过滤掉保留地址。

3.4 广播地址

广播地址(General Call Address)是I2C协议中一个特殊的地址,其7位地址为0x00。当主设备发送广播地址时,所有支持广播功能的从机都应应答并接收后续数据。

  • 广播格式:起始条件 + 0x00(写操作)+ 应答 + 数据字节 + 停止条件。
  • 用途:
    • 全局复位:主设备发送广播地址后,再发送复位命令字节(如0x06),所有从机执行软复位。
    • 全局配置:主设备向所有从机广播相同的配置参数(如采样率、工作模式)。
    • 地址分配:某些系统使用广播地址为未配置的从机动态分配地址。
  • 从机响应:从机可以通过寄存器位(如GENERAL_CALL_EN)使能或禁用广播响应。在MCU驱动中,通常默认禁用广播响应,除非有特殊需求。
驱动实现提示:在配置I2C从机地址寄存器时,如果芯片支持广播地址,务必确认是否需要在初始化时使能广播响应。大多数应用场景下,广播地址应保持禁用,以避免意外响应。

3.5 地址格式与应答时序关系图

下图展示了7位地址和10位地址在I2C总线上的完整传输时序,包括起始条件、地址字节、应答位以及数据阶段的关系。

I2C 7位地址与10位地址传输时序对比 I2C 7位地址与10位地址传输时序对比 7位地址传输: S 地址字节 R/W ACK 数据... P 10位地址传输: S 11110 A9 A8 R/W ACK 低8位地址 ACK 数据... P 广播地址传输: S 0x00 (W) ACK 命令字节 P 关键说明: 1. S = 起始条件 (Start Condition);P = 停止条件 (Stop Condition);ACK = 应答位 (Acknowledge)。 2. 7位地址:地址字节包含7位地址 + 1位R/W,从机在ACK阶段拉低SDA表示应答。 3. 10位地址:需要两个地址字节 + 两次应答,第一个字节前5位固定为11110。 4. 广播地址:地址为0x00(写操作),所有支持广播的从机都应应答,常用于全局复位或配置。

3.6 地址配置寄存器示例

在MCU驱动中,配置I2C从机地址通常涉及以下寄存器操作。以下以常见的STM32 I2C外设为例,展示7位地址和10位地址的配置代码:

// 7位地址配置示例(STM32 I2C从机模式)
#define I2C_OWN_ADDRESS7    0x32    // 7位从机地址

void I2C_Slave_Init_7bit(void)
{
    // 使能I2C时钟
    RCC->APB1ENR |= RCC_APB1ENR_I2C1EN;
    
    // 配置I2C控制寄存器
    I2C1->CR1 = 0;
    I2C1->CR2 = 36;                     // 36MHz外设时钟
    
    // 设置从机地址寄存器(7位地址需左移1位)
    I2C1->OAR1 = (0x32 << 1) | (0x01 << 14);  // 7位地址模式,使能地址匹配
    // 注意:OAR1的bit14=1表示使能该地址,bit15=0表示7位地址模式
    
    // 使能I2C外设
    I2C1->CR1 |= I2C_CR1_PE;
}

// 10位地址配置示例
#define I2C_OWN_ADDRESS10   0x01A3    // 10位从机地址

void I2C_Slave_Init_10bit(void)
{
    // 使能I2C时钟
    RCC->APB1ENR |= RCC_APB1ENR_I2C1EN;
    
    // 配置I2C控制寄存器
    I2C1->CR1 = 0;
    I2C1->CR2 = 36;
    
    // 设置从机地址寄存器(10位地址模式)
    I2C1->OAR1 = (0x01A3 & 0x03FF) | (0x01 << 15) | (0x01 << 14);
    // bit15=1表示10位地址模式,bit14=1使能地址匹配
    // 地址值直接写入低10位
    
    // 使能I2C外设
    I2C1->CR1 |= I2C_CR1_PE;
}
寄存器配置要点:
- 7位地址:地址值左移1位后写入OAR1,确保bit15=0(7位模式),bit14=1(使能地址匹配)。
- 10位地址:地址值直接写入OAR1的低10位,设置bit15=1(10位模式),bit14=1(使能地址匹配)。
- 广播地址:通常通过独立的寄存器位(如OAR2或CR2中的GENCALL位)使能或禁用广播响应。

3.7 地址冲突检测与调试

在MCU驱动开发中,地址配置错误是I2C通信失败的常见原因。以下是一些实用的检测与调试方法:

  • 逻辑分析仪抓取:使用逻辑分析仪捕获SDA和SCL波形,检查起始条件后的第一个字节是否与预期地址一致。
  • 地址回读验证:配置完成后,读取从机地址寄存器,确认写入值与预期值一致。
  • 保留地址过滤:在驱动初始化代码中加入地址范围检查,避免使用0x00~0x07及0x78~0x7F等保留地址。
  • 多从机冲突排查:如果总线上有多个从机,逐一断开非目标设备,确认地址唯一性。
调试陷阱:某些MCU的I2C外设支持双地址模式(如OAR1和OAR2),如果误配置了多个地址,可能导致从机响应异常。务必检查芯片手册,确认地址寄存器的优先级和掩码规则。