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 位。
| 位序号 | 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) | 写操作 | ||||||
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。
| 传输阶段 | 字节内容 | 高 5 位 | 地址高位 | R/W | 说明 |
|---|---|---|---|---|---|
| 第 1 字节 | 0xF0 (11110 000) | 11110 | A9=0, A8=0 | 0 (写) | 标识 + 地址高位 + 写操作 |
| 第 2 字节 | 0xB1 (1011 0001) | 低 8 位地址 (A7~A0) | |||
3.3 从机应答机制(ACK/NACK)
I2C 总线要求每个传输的字节(包括地址字节和数据字节)之后,接收方必须提供一个应答位。这是 I2C 协议实现可靠通信的基础。
- ACK(应答,低电平):在第 9 个 SCL 时钟周期,接收方将 SDA 线拉低,表示“已成功接收字节,可以继续发送下一个字节”。
- NACK(非应答,高电平):在第 9 个 SCL 时钟周期,接收方保持 SDA 线为高电平(释放总线),表示“未成功接收”或“传输结束”。
常见异常分析:
- 地址阶段 NACK:最常见的原因是从机地址错误、从机未上电、总线被拉死或从机忙。这是调试初期最需要排查的问题。
- 数据阶段 NACK:通常发生在读操作时,主设备在读取最后一个字节后发送 NACK 以通知从机停止发送;或在写操作时,从机因接收缓冲区满而主动 NACK。
| 阶段 | 信号状态 | 含义 | 调试排查方向 |
|---|---|---|---|
| 地址字节后 | ACK (SDA 低) | 从机存在且准备好通信 | 地址匹配,硬件连接正常 |
| 地址字节后 | NACK (SDA 高) | 从机无响应 | 检查地址、上电、复位、总线冲突 |
| 数据字节后(写) | ACK (SDA 低) | 从机已接收数据 | 正常传输 |
| 数据字节后(写) | NACK (SDA 高) | 从机无法接收更多数据 | 检查从机状态寄存器、FIFO 是否满 |
| 数据字节后(读) | 主设备发送 ACK | 主设备请求继续发送 | 正常读取多个字节 |
| 数据字节后(读) | 主设备发送 NACK | 主设备要求停止发送 | 读取最后一个字节后的标准行为 |
3.4 综合波形验证流程
在调试 I2C 外设驱动时,建议按照以下步骤在逻辑分析仪或示波器上验证地址与应答时序:
- 确认起始条件:SCL 高电平时,SDA 出现下降沿。
- 解析地址字节:读取 SCL 第 1-8 个脉冲对应的 SDA 电平,组合成 8 位数据。验证高 7 位是否为目标地址,Bit 0 是否为正确的 R/W 值。
- 检查应答位:在第 9 个 SCL 脉冲的上升沿附近采样 SDA。若为低电平(ACK),继续;若为高电平(NACK),停止并排查地址或硬件问题。
- 重复数据字节:对于后续的数据字节,重复步骤 2 和 3,直到传输结束。
- 确认停止条件:SCL 高电平时,SDA 出现上升沿。
实战案例: 某温度传感器驱动在读取温度时始终返回 0xFF。抓取波形后发现,主设备发送的地址字节为 0x91(读操作),但传感器手册要求的地址是 0x90(写操作)和 0x91(读操作)。波形显示传感器在地址字节后回复了 NACK。修正驱动中地址左移逻辑后,通信恢复正常。