第二讲:物理层揭秘 — SCL与SDA、开漏输出与上拉电阻
这一讲,咱们彻底搞懂I2C的物理层。说白了,就是两根线(SCL和SDA)是怎么把数据传起来的。
很多新手一上来就看时序图、读寄存器,结果遇到干扰或者接不上设备,就一脸懵。嗯,物理层没吃透,后面肯定要吃亏的。我当年第一个I2C项目,就是因为上拉电阻选得不对,折腾了两天没搞定通信。
2.1 两条线的故事:SCL 与 SDA
I2C总线就两根线:
- SCL(串行时钟线):由主设备驱动,负责提供通信的节奏。
- SDA(串行数据线):双向传输数据。主设备发、从设备收,或者反过来。
你想想看,一个房间里几十个人(设备),就靠这两根线互相说话,是不是很神奇?
这两根线有一个共同的特点:空闲时都是高电平。这是靠外部上拉电阻拉高的。谁要说话,就把对应的线拉低。
2.2 核心机制:开漏输出
这是I2C物理层最精髓的地方。为什么设备能共用一根线?为什么不会短路?答案就是——开漏输出。
开漏输出,你可以理解为:
- 内部晶体管只负责把引脚拉低到GND(0V)。
- 输出高电平?它不管,全靠外部上拉电阻拉上去。
这样一来,如果两个设备同时想把SDA线拉低,没问题,它们只是同时导通了内部的下拉管,线还是低电平。但如果有一个设备想输出高电平、一个想输出低电平,按照普通推挽输出,那两个管子就打架了,电流会很大,甚至烧坏芯片。
在开漏模式下,想输出高电平的设备“什么都不做”,把引脚下拉管关掉,靠外部电阻自然把线拉高。所以,多设备共享一根线时,不会发生电源对地的短路。这也是I2C能挂几十个设备的基础。
2.3 上拉电阻:作用与选型
既然设备自己拉不高电平,那就需要外接一个电阻,把SCL和SDA连接到VDD(一般是3.3V或5V)。这个电阻就是上拉电阻。
它的两个核心作用:
- 保证空闲高电平:没人拉低时,总线自动回到高电平,这是I2C的起始/停止条件的前提。
- 决定信号上升速度:因为开漏输出只能快速拉低,但拉高靠电阻慢慢“充电”,所以电阻大小直接影响通信速率。
电阻选型怎么算?
选型主要参考I2C规范里的两个限制:
| 参数 | 标准模式 (100kHz) | 快速模式 (400kHz) | 高速模式 (3.4MHz) |
|---|---|---|---|
| 最大上升时间 (tr) | 1000 ns | 300 ns | 120 ns |
| 总线电容 (Cb) | ≤400 pF | ≤400 pF | ≤100 pF |
计算公式:
- 最小电阻 Rmin:保证拉低时灌电流不超过芯片允许值。一般VDD=3.3V,IOLmax=3mA,则Rmin = 3.3V / 3mA ≈ 1.1kΩ。
- 最大电阻 Rmax:保证信号上升时间不超过规范值。 tr ≈ 0.847 × R × Cb。假设Cb=200pF,快速模式允许tr=300ns,则Rmax = 300ns / (0.847 × 200pF) ≈ 1.77kΩ。
- VDD=3.3V,总线设备少(≤4个,短线):4.7kΩ
- VDD=3.3V,总线设备多(6-8个,长线):2.2kΩ 或 1.8kΩ
- VDD=5V:可适当增大到5.1kΩ ~ 10kΩ
我个人习惯,拿到新板子,先用4.7kΩ。如果400kHz通信不稳定再换成2.2kΩ。具体选多大,自己用示波器看看上升沿陡不陡就行。
2.4 总线电平与电压兼容
I2C协议本身对电平有定义:
- 低电平(L):低于0.3×VDD
- 高电平(H):高于0.7×VDD
但现实是,主设备可能是3.3V的MCU,从设备可能是5V的传感器。怎么让它们一起工作?
电平兼容的3种常见做法
- 直接连接(仅限3.3V设备容忍5V):检查从设备的数据手册,如果它标注了“5V tolerant”,那就直接用。上拉电阻接3.3V即可。但要注意,有些5V设备需要输入高电平至少0.7×5V≈3.5V,那3.3V可能不够。
- 电平转换芯片:例如PCA9306、TXS0102。专为不同电压域设计,稳定性最好。项目可靠性要求高时,我建议用这种。
- 分立元件电平转换(适合低成本):用一对NMOS管和两个上拉电阻搭建。原理很简单:从3.3V到5V方向,NMOS导通拉低时,5V侧也被拉低;NMOS截止时,5V侧被5V上拉电阻拉高。这样两边就兼容了。
2.5 本章知识结构
下面这张图,帮大家把物理层的核心关系理清楚。两条线、开漏空、上拉电阻、电平兼容,就是一个完整的知识闭环。
好了,物理层基本讲完了。记住三句话:
- 两条线(SCL+SDA),靠开漏输出实现多设备共享。
- 上拉电阻是I2C的“默认高电平”,选型要权衡功耗和速度。
- 不同电压域的设备一定要处理好电平兼容,否则通信会出各种怪问题。