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为总线寄生电容)。电阻越小,上升时间越短,但静态功耗越大。

下图展示了开漏输出与上拉电阻的电气连接关系:

I2C开漏输出与上拉电阻电气连接图 I2C开漏输出与上拉电阻电气连接 VDD (3.3V) R1 R2 SDA SCL 主设备 (Master) MOS 从设备1 (Slave 1) MOS 从设备2 (Slave 2) MOS 工作原理: 1. 所有MOSFET截止 → 总线被R1/R2拉高 2. 任一MOSFET导通 → 总线被拉低 3. 多个设备可同时拉低总线(线与)

2.4 总线仲裁

I2C总线支持多主设备通信。当多个主设备同时尝试控制总线时,通过总线仲裁机制决定哪个主设备获得总线控制权。仲裁过程完全基于开漏输出和“线与”特性,无需额外的仲裁器。

2.4.1 仲裁原理

  1. 数据竞争: 多个主设备在SCL的每个时钟周期同时向SDA线发送数据位。
  2. 线与检测: 如果一个主设备试图发送高电平(释放SDA),但检测到SDA为低电平(被另一个主设备拉低),则该主设备知道自己失去了仲裁。
  3. 退出与重试: 失去仲裁的主设备必须立即释放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 继续

下图展示了两个主设备同时发起传输时的仲裁流程:

I2C总线仲裁流程图 I2C总线仲裁流程 多个主设备开始传输 发送起始条件 逐位发送地址/数据 检测SDA电平 失去仲裁 释放总线 赢得仲裁 继续传输 仲裁基于“线与”特性: 发送高电平但检测到低电平则失败

2.5 物理层对GPIO模拟的影响

使用GPIO模拟I2C时,必须严格遵循物理层特性,否则通信将失败:

  • 开漏输出模拟: GPIO必须配置为开漏模式(如果MCU支持)或通过软件控制输出寄存器实现类似效果(输出0时拉低,输出1时切换为输入高阻态)。
  • 上拉电阻配置: 必须确保SDA和SCL线有合适的上拉电阻。如果使用MCU内部上拉,需确认其阻值是否满足总线速度要求(通常内部上拉为30kΩ~50kΩ,仅适用于低速或单设备场景)。
  • 仲裁检测: 在GPIO模拟实现中,如果系统为单主设备,可以忽略仲裁逻辑;但在多主设备系统中,必须实现SDA电平的读取与比较。
GPIO模拟I2C的物理层关键点: 模拟的核心在于精确控制GPIO的输出状态(拉低/高阻)和时序(SCL高低电平保持时间)。任何时序偏差都可能导致从设备无法正确采样数据或产生错误应答。