3、I2C寻址与通信流程:7位寻址与10位寻址、读写操作流程、多主机仲裁
好,咱们今天聊聊I2C的寻址和通信流程。这部分内容,说白了就是I2C总线上设备之间怎么「打招呼」、怎么「传话」的规矩。你搞懂了这些,写驱动的时候心里就有底了。
3.1 7位寻址与10位寻址
I2C总线上每个设备都有一个唯一的地址。主机发数据前,得先喊一声这个地址,告诉总线「我要找谁」。这个地址有两种格式:7位和10位。
3.1.1 7位寻址
这是最常用的方式。地址占7个bit,加上一个读写位(R/W),凑成一个字节发送出去。
地址范围是0x00到0x7F。但要注意,0x00是通用呼叫地址,0x01是起始字节,0x02到0x07保留,0x78到0x7F也是保留地址。所以实际可用的地址大概在0x08到0x77之间。
地址格式:
| 7-bit Address | R/W |
| A6 A5 A4 A3 A2 A1 A0 | 0/1 |
- R/W = 0:主机要写数据到从机
- R/W = 1:主机要从从机读数据
3.1.2 10位寻址
7位地址最多挂127个设备,有些场景不够用。10位寻址就解决了这个问题,地址范围扩展到0x000到0x3FF。
10位寻址的发送分两步:
- 第一个字节:高5位是11110,接着是地址的高2位(A9、A8),最后是R/W位。
- 第二个字节:地址的低8位(A7~A0)。
格式如下:
第一个字节: | 1 1 1 1 0 | A9 A8 | R/W |
第二个字节: | A7 A6 A5 A4 A3 A2 A1 A0 |
3.2 读写操作流程
I2C的通信流程,核心就是「起始信号 → 发送地址 → 读写数据 → 停止信号」。咱们分写操作和读操作来说。
3.2.1 写操作流程
主机往从机写数据,流程如下:
- 起始信号(S):SCL高电平时,SDA从高变低。
- 发送从机地址 + 写位:7位地址左移一位,最低位为0。
- 等待应答(ACK):从机拉低SDA表示应答。
- 发送寄存器地址:告诉从机你要写哪个寄存器。
- 等待应答(ACK)。
- 发送数据字节:可以连续发多个字节。
- 每发一个字节,等待一次应答。
- 停止信号(P):SCL高电平时,SDA从低变高。
时序图(简化):
S | Addr+W | ACK | RegAddr | ACK | Data1 | ACK | Data2 | ACK | ... | P
3.2.2 读操作流程
读操作比写操作多一个步骤——需要先写寄存器地址,再重新发送起始信号,然后读数据。
- 起始信号(S)。
- 发送从机地址 + 写位。
- 等待应答。
- 发送要读取的寄存器地址。
- 等待应答。
- 重复起始信号(Sr):SCL高电平时,SDA再次从高变低。
- 发送从机地址 + 读位。
- 等待应答。
- 读取数据字节:主机每读一个字节,要发送ACK(表示还要继续读)或NACK(表示读完了)。
- 停止信号(P)。
时序图:
S | Addr+W | ACK | RegAddr | ACK | Sr | Addr+R | ACK | Data1 | ACK | Data2 | NACK | P
3.3 多主机仲裁
I2C总线允许多个主机同时发起通信。但总线只有一根SDA和一根SCL,冲突了怎么办?这就靠仲裁机制来解决。
3.3.1 仲裁原理
仲裁发生在SDA线上。多个主机同时发送数据时,谁先拉低SDA,谁就赢得仲裁。因为I2C总线是开漏输出,低电平会覆盖高电平。
仲裁过程:
- 每个主机在发送数据时,会同时监测SDA电平。
- 如果某个主机发送了高电平,但检测到SDA是低电平,说明有其他主机在拉低总线。
- 这个主机就知道自己仲裁失败了,立即停止发送,转为从机模式。
- 仲裁获胜的主机继续通信,不受影响。
3.3.2 仲裁与地址的关系
仲裁不仅发生在数据阶段,也发生在地址阶段。多个主机同时发送地址时,谁的地址小(二进制值小),谁更容易赢得仲裁。因为地址小的主机,会在某个位上先拉低SDA。
举个例子:
| 主机 | 发送地址(二进制) | 仲裁结果 |
|---|---|---|
| 主机A | 1010 000 | 失败(第5位为1,被拉低) |
| 主机B | 1010 001 | 获胜(第5位为0,拉低总线) |
3.3.3 多主机系统的设计建议
如果你在设计多主机系统,有几点要注意:
- 每个主机要有唯一的地址:仲裁时,地址小的主机优先级高。如果你想让某个主机优先通信,给它分配一个较小的地址。
- 处理仲裁失败:仲裁失败的主机需要重试。我建议加一个重试机制,比如等待随机时间后再尝试。否则两个主机可能一直冲突。
- 使用总线空闲检测:在发起通信前,先检测总线是否空闲(SDA和SCL都为高)。这样可以减少冲突概率。
3.4 本章知识体系
下面这张图帮你梳理了本章的核心逻辑:
嗯,这一章的内容就这些。寻址和通信流程是I2C的基础,你写驱动时天天都会用到。多主机仲裁虽然不常见,但理解了它的原理,遇到问题时就能快速定位。下一章咱们聊聊I2C的时序参数和电气特性,到时候我会分享一些调试经验。