3. I2C 地址与读写:7位地址与10位地址格式、读写位(R/W)控制、从机应答机制(ACK/NACK)

在 I2C 总线协议中,地址、读写控制与应答机制是构成一次完整传输会话的三大核心要素。地址决定了主设备与哪个从设备通信;读写位决定了数据流的方向;应答位则提供了总线级别的传输确认。调试 I2C 外设驱动时,波形上的地址字节、R/W 位以及 ACK/NACK 信号是首先需要验证的关键时序点。

3.1 7位地址格式与读写位(R/W)

标准 I2C 总线使用 7 位从机地址,这是最广泛使用的地址模式。主设备在发送起始条件(START)后,紧接着发送的第一个字节(8 位)包含了 7 位地址和 1 位读写控制位(R/W)。

  • 高 7 位(Bit 7 ~ Bit 1):从机地址。由器件型号的固定部分和可配置的引脚电平决定。
  • 最低位(Bit 0):读写位(R/W)。0 表示主设备将要写数据到从机;1 表示主设备将要读取从机数据。
调试要点: 在逻辑分析仪或示波器上观察起始条件后的第一个字节时,务必确认该字节的高 7 位与目标器件的数据手册一致,且 R/W 位符合当前操作意图。常见的错误是地址左移一位后未正确设置 R/W 位。
7位地址字节结构示例(地址 0x48,写操作)
位序号 Bit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0 (R/W)
值 1 0 0 1 0 0 0 0
含义 7位地址 = 0x48 (1001000) 写操作
7位地址 + R/W 位在 SDA 线上的传输顺序 START A6 A5 A4 A3 A2 A1 A0 R/W ACK 波形验证要点 1. 确认 SCL 时钟的第 1-7 个脉冲对应地址位,第 8 个脉冲对应 R/W 位,第 9 个脉冲对应从机 ACK。 2. 地址位顺序为 MSB(A6)到 LSB(A0),R/W=0 表示写,R/W=1 表示读。

3.2 10位地址格式

当系统中从机数量超过 112 个(7 位地址上限)或需要更灵活的地址分配时,I2C 规范定义了 10 位地址模式。10 位地址的传输需要两个字节来完成。

  • 第一个字节(头字节):高 5 位固定为 11110,作为 10 位地址的标识。接下来的两位(Bit 2 和 Bit 1)是 10 位地址的最高两位(A9 和 A8)。Bit 0 仍然是 R/W 位。
  • 第二个字节:完整的 8 位数据,包含 10 位地址的低 8 位(A7 ~ A0)。
驱动开发提示: 大多数通用 MCU 的 I2C 外设硬件会自动处理 10 位地址的发送序列。但在纯软件模拟 I2C(Bit-banging)或调试底层波形时,必须手动构造这两个字节。注意第一个字节的格式是 11110 A9 A8 R/W。
10位地址传输序列示例(地址 0x2B1,写操作)
传输阶段 字节内容 高 5 位 地址高位 R/W 说明
第 1 字节 0xF0 (11110 000) 11110 A9=0, A8=0 0 (写) 标识 + 地址高位 + 写操作
第 2 字节 0xB1 (1011 0001) 低 8 位地址 (A7~A0)
10位地址传输序列(两个字节) 11110 标识位 A9 A8 R/W ACK 低 8 位地址 (A7 ~ A0) ACK 注意:10位地址模式下,从机在第一个字节和第二个字节后都需要回复 ACK。 第一个字节的 R/W 位决定后续所有数据的方向,直到 STOP 或重复起始条件。

3.3 从机应答机制(ACK/NACK)

I2C 总线要求每个传输的字节(包括地址字节和数据字节)之后,接收方必须提供一个应答位。这是 I2C 协议实现可靠通信的基础。

  • ACK(应答,低电平):在第 9 个 SCL 时钟周期,接收方将 SDA 线拉低,表示“已成功接收字节,可以继续发送下一个字节”。
  • NACK(非应答,高电平):在第 9 个 SCL 时钟周期,接收方保持 SDA 线为高电平(释放总线),表示“未成功接收”或“传输结束”。
常见异常分析:
  • 地址阶段 NACK:最常见的原因是从机地址错误、从机未上电、总线被拉死或从机忙。这是调试初期最需要排查的问题。
  • 数据阶段 NACK:通常发生在读操作时,主设备在读取最后一个字节后发送 NACK 以通知从机停止发送;或在写操作时,从机因接收缓冲区满而主动 NACK。
ACK/NACK 状态与调试含义
阶段 信号状态 含义 调试排查方向
地址字节后 ACK (SDA 低) 从机存在且准备好通信 地址匹配,硬件连接正常
地址字节后 NACK (SDA 高) 从机无响应 检查地址、上电、复位、总线冲突
数据字节后(写) ACK (SDA 低) 从机已接收数据 正常传输
数据字节后(写) NACK (SDA 高) 从机无法接收更多数据 检查从机状态寄存器、FIFO 是否满
数据字节后(读) 主设备发送 ACK 主设备请求继续发送 正常读取多个字节
数据字节后(读) 主设备发送 NACK 主设备要求停止发送 读取最后一个字节后的标准行为
ACK/NACK 应答时序图(第 9 个 SCL 时钟) SCL 1 2 3 4 5 6 7 8 9 SDA D7 D6 D5 D4 D3 D2 D1 D0 ACK 波形验证:在第 9 个 SCL 时钟的上升沿采样 SDA 电平。低电平 = ACK,高电平 = NACK。 主设备在发送完 8 位数据后释放 SDA 总线,由接收方控制 SDA 输出。

3.4 综合波形验证流程

在调试 I2C 外设驱动时,建议按照以下步骤在逻辑分析仪或示波器上验证地址与应答时序:

  1. 确认起始条件:SCL 高电平时,SDA 出现下降沿。
  2. 解析地址字节:读取 SCL 第 1-8 个脉冲对应的 SDA 电平,组合成 8 位数据。验证高 7 位是否为目标地址,Bit 0 是否为正确的 R/W 值。
  3. 检查应答位:在第 9 个 SCL 脉冲的上升沿附近采样 SDA。若为低电平(ACK),继续;若为高电平(NACK),停止并排查地址或硬件问题。
  4. 重复数据字节:对于后续的数据字节,重复步骤 2 和 3,直到传输结束。
  5. 确认停止条件:SCL 高电平时,SDA 出现上升沿。
实战案例: 某温度传感器驱动在读取温度时始终返回 0xFF。抓取波形后发现,主设备发送的地址字节为 0x91(读操作),但传感器手册要求的地址是 0x90(写操作)和 0x91(读操作)。波形显示传感器在地址字节后回复了 NACK。修正驱动中地址左移逻辑后,通信恢复正常。