2. I2C协议基础:物理层特性与总线机制
I2C(Inter-Integrated Circuit)总线是一种由Philips(现NXP)开发的同步、多主从、串行通信总线。它仅需两根信号线即可完成设备间的数据交换,是嵌入式系统中使用最广泛的板级总线之一。理解其物理层特性是后续用GPIO模拟I2C时序的基础。
2.1 物理层核心特性
I2C总线的物理层设计决定了其简洁性与可靠性,核心特性如下表所示:
| 特性 | 描述 | 典型值/范围 |
|---|---|---|
| 信号线数量 | 串行数据线(SDA)和串行时钟线(SCL) | 2根 |
| 输出类型 | 开漏(Open-Drain)输出 | — |
| 上拉电阻 | 外部上拉电阻将总线拉至高电平 | 1kΩ ~ 10kΩ(取决于总线电容和速度) |
| 逻辑电平 | 低电平=GND,高电平=VDD(由上拉电压决定) | 1.8V / 3.3V / 5V |
| 总线电容 | 限制最大从设备数量和通信速率 | 标准模式≤400pF |
| 最大从设备数 | 受限于7位或10位地址空间和总线电容 | 理论127个(7位地址) |
2.2 SDA与SCL线
SDA(Serial Data Line) 和 SCL(Serial Clock Line) 是I2C总线的两条物理信号线:
- SDA:用于传输地址、数据和应答信号。数据在SCL低电平时变化,在SCL高电平时被采样。
- SCL:由主设备产生的时钟信号,同步所有总线上的数据传输。每个时钟脉冲传输1位数据。
关键时序约束: 在标准模式(100kHz)下,SCL高电平和低电平的最小保持时间均为4.0μs;在快速模式(400kHz)下,该时间缩短至0.6μs。GPIO模拟时必须严格满足这些时序要求。
2.3 开漏输出与上拉电阻
I2C总线的核心物理机制是开漏输出与上拉电阻的组合。理解这一机制是掌握总线仲裁和GPIO模拟的关键。
2.3.1 开漏输出原理
开漏输出意味着设备的SDA和SCL引脚内部仅包含一个N沟道MOSFET,其漏极(Drain)连接到外部引脚,源极(Source)接地。当MOSFET导通时,引脚被拉至GND(低电平);当MOSFET截止时,引脚处于高阻态(Hi-Z),此时引脚电平由外部上拉电阻决定。
开漏输出的本质: 设备只能主动将总线拉低,无法主动拉高。总线的高电平完全由外部上拉电阻提供。这种设计允许多个设备的输出直接“线与”连接,而不会发生短路。
2.3.2 上拉电阻的作用
- 提供高电平: 当所有设备的开漏输出都截止时,上拉电阻将总线电压拉至VDD。
- 限制电流: 当设备拉低总线时,上拉电阻限制了从VDD到GND的电流,防止损坏器件。
- 决定上升时间: 总线从低电平到高电平的上升时间由RC常数决定(R为上拉电阻,C为总线寄生电容)。电阻越小,上升时间越短,但静态功耗越大。
下图展示了开漏输出与上拉电阻的电气连接关系:
2.4 总线仲裁
I2C总线支持多主设备通信。当多个主设备同时尝试控制总线时,通过总线仲裁机制决定哪个主设备获得总线控制权。仲裁过程完全基于开漏输出和“线与”特性,无需额外的仲裁器。
2.4.1 仲裁原理
- 数据竞争: 多个主设备在SCL的每个时钟周期同时向SDA线发送数据位。
- 线与检测: 如果一个主设备试图发送高电平(释放SDA),但检测到SDA为低电平(被另一个主设备拉低),则该主设备知道自己失去了仲裁。
- 退出与重试: 失去仲裁的主设备必须立即释放SDA和SCL线,并在总线空闲后重新尝试发送。
仲裁注意事项: 仲裁不会丢失数据,因为获胜的主设备发送的数据位与总线状态一致。仲裁过程可能发生在起始条件、地址字节或数据字节的传输过程中。地址字节的仲裁实际上实现了“多主设备寻址冲突解决”。
2.4.2 仲裁过程示例
假设两个主设备(Master A和Master B)同时开始发送数据:
| 时钟周期 | Master A 发送 | Master B 发送 | SDA总线状态 | 仲裁结果 |
|---|---|---|---|---|
| 1 | 1(释放) | 1(释放) | 1(高电平) | 继续 |
| 2 | 0(拉低) | 1(释放) | 0(低电平) | Master B 失去仲裁 |
| 3 | 0(拉低) | —(已退出) | 0(低电平) | Master A 继续 |
下图展示了两个主设备同时发起传输时的仲裁流程:
2.5 物理层对GPIO模拟的影响
使用GPIO模拟I2C时,必须严格遵循物理层特性,否则通信将失败:
- 开漏输出模拟: GPIO必须配置为开漏模式(如果MCU支持)或通过软件控制输出寄存器实现类似效果(输出0时拉低,输出1时切换为输入高阻态)。
- 上拉电阻配置: 必须确保SDA和SCL线有合适的上拉电阻。如果使用MCU内部上拉,需确认其阻值是否满足总线速度要求(通常内部上拉为30kΩ~50kΩ,仅适用于低速或单设备场景)。
- 仲裁检测: 在GPIO模拟实现中,如果系统为单主设备,可以忽略仲裁逻辑;但在多主设备系统中,必须实现SDA电平的读取与比较。
GPIO模拟I2C的物理层关键点: 模拟的核心在于精确控制GPIO的输出状态(拉低/高阻)和时序(SCL高低电平保持时间)。任何时序偏差都可能导致从设备无法正确采样数据或产生错误应答。