I2C总线物理层:SDA/SCL、上拉电阻与电平标准
搞I2C协议,第一步不是看时序图,而是先把物理层搞明白。说白了,就是那两根线——SDA和SCL,到底是怎么工作的。很多新手一上来就盯着数据手册里的时序参数看,结果板子调不通,最后发现是上拉电阻没选对。嗯,这坑我踩过不止一次。
SDA与SCL:两根线的“默契”
I2C总线只有两根线:SDA (Serial Data Line) 和 SCL (Serial Clock Line)。这俩是双向的,也就是说,主设备和从设备都能拉低它们。你想想看,如果两边同时输出高低电平,那不就短路了吗?
所以,I2C的物理层有一个关键设计——开漏输出(Open-Drain)。每个设备的SDA和SCL引脚内部都是一个MOS管的漏极,它只能拉低到GND,或者释放成高阻态。释放之后,线就被外部的上拉电阻拉到高电平。
开漏输出的本质: 设备只能主动拉低,不能主动拉高。高电平全靠上拉电阻“托着”。
我记得在做一个多从机项目时,有个从机芯片的SDA引脚内部竟然不是开漏,而是推挽输出。结果一上电,总线直接锁死,数据根本没法传。从那以后,我对每个从机的手册都会多看一眼引脚结构。
上拉电阻:选大了还是选小了?
上拉电阻的取值,是物理层里最容易被忽视、也最容易出问题的地方。选大了,信号上升沿太慢,高频通信容易出错;选小了,灌电流太大,功耗高,甚至可能损坏端口。
标准I2C模式(100kHz)下,上拉电阻的典型范围是 4.7kΩ ~ 10kΩ。快速模式(400kHz)就需要小一点,比如 2.2kΩ ~ 4.7kΩ。我个人的习惯是:
- 总线电容小(比如只有一两个从机):选 4.7kΩ 起步,稳妥
- 总线电容大(长走线、多从机):选 2.2kΩ,保证上升沿够陡
- 超低功耗场景:可以选 10kΩ,但要注意总线速度不能太高
快速估算公式:
上升沿时间 Tr ≈ 0.847 × R_p × C_bus
一般要求 Tr < 0.3 × T_scl(SCL周期),用这个反推出R_p的上下限。
我曾经在一个项目里,为了省电把上拉电阻改成了22kΩ。结果400kHz模式下,上升沿都快赶上半个时钟周期了,从机根本采不到正确的电平。后来用逻辑分析仪一看,SDA的波形就像慢动作回放——嗯,老老实实换回4.7kΩ,问题解决。
电平标准:3.3V还是5V?
I2C本身不是一种固定的电平标准,它说的是总线上的高电平由VDD决定。也就是说,你用3.3V供电,高电平就是3.3V;用5V供电,高电平就是5V。
问题来了:如果主控是3.3V,从机是5V,怎么共存?
答案就是——电平转换。I2C总线的开漏结构,天然支持多电平互联。只要满足两个条件:
- 所有设备的高电平阈值,都高于总线上拉电压
- 所有设备的低电平阈值,都低于0.3×VDD(一般0.8V就够)
说白了,只要上拉电阻接的是3.3V,那么整个总线的逻辑高就是3.3V。5V的从机如果支持“3.3V输入容忍”(3.3V-tolerant),就可以直接挂上去。
| 项目 | 标准I2C (100kHz) | 快速模式 (400kHz) | 快速模式+ (1MHz) |
|---|---|---|---|
| 典型上拉电阻 | 4.7kΩ ~ 10kΩ | 2.2kΩ ~ 4.7kΩ | 1.5kΩ ~ 2.2kΩ |
| 最大总线电容 | 400pF | 400pF | 550pF |
| 低电平阈值 | 0.3 × VDD | 0.3 × VDD | 0.3 × VDD |
| 高电平阈值 | 0.7 × VDD | 0.7 × VDD | 0.7 × VDD |
实际项目中,我建议直接用逻辑分析仪抓一下SDA和SCL的上升沿。如果看到上升沿像个圆弧一样慢慢爬上去,说明你的上拉电阻太大了;如果波形方方正正但没有过冲,那就很理想。
注意: 千万不要在3.3V总线上直接挂一个5V的推挽输出设备。一旦它输出高电平,会通过上拉电阻往3.3V电源灌电流,轻则电平紊乱,重则烧端口。
总结一下物理层的几个关键点
到现在你应该明白了:I2C的物理层核心就是开漏 + 上拉。这两根线看似简单,但选错电阻、搞混电平、忽略总线电容,都会让你在调试时抓狂。
我个人在调试I2C时,第一件事就是用逻辑分析仪看波形:
- SDA和SCL在空闲时是不是都被拉到高电平?
- 下降沿是不是够陡?
- 上升沿有没有明显拖尾?
如果这三个问题都没毛病,那物理层基本就过关了。