1. I2C协议基础:物理层特性、总线拓扑结构、开漏输出与上拉电阻

各位同学,咱们正式开始这门课。第一讲,先把I2C协议的老底儿翻出来看看。很多人调I2C调不通,上来就查代码、看时序,结果折腾半天发现是硬件上拉电阻没焊,或者总线电容太大。嗯,这种坑我踩过不止一次。所以今天咱们从物理层讲起,把根扎稳。

1.1 物理层特性:两根线怎么干活?

I2C总线就两根线:SCL(时钟线)和SDA(数据线)。所有设备都挂在这两根线上。你想想看,如果多个设备同时往一根线上输出高低电平,那不就打架了吗?

I2C的解决方案很巧妙——开漏输出。每个设备的SCL和SDA引脚内部都是一个N沟道MOS管的漏极,它只能把线拉低到GND,不能主动拉高。那高电平谁来给?上拉电阻。

核心要点:开漏输出 + 上拉电阻 = 线与逻辑。任何设备拉低总线,总线就是低电平;所有设备都释放(高阻),总线才被上拉电阻拉到高电平。

我在一个项目里遇到过这种情况:两个从机地址冲突,其中一个偷偷把SDA拉死了,主机怎么发起始信号都没反应。当时用示波器一看,SDA一直低电平,就知道有设备在“霸占”总线。这就是开漏输出的特性——谁都能拉低,但谁都不能单独拉高。

1.2 总线拓扑结构:一主多从还是多主多从?

I2C是多主从总线。理论上可以有多个主机,但实际项目中绝大多数情况是单主机——一个STM32挂一堆传感器、EEPROM、IO扩展芯片。

总线拓扑就是一根SCL、一根SDA,所有设备并联。每个设备都有一个唯一的7位或10位地址。主机通过地址来选择跟谁通信。

参数 标准模式 快速模式 高速模式
最大时钟频率 100 kHz 400 kHz 3.4 MHz
最大总线电容 400 pF 400 pF 100 pF
最大从机数量 127(7位地址) 127 127
上拉电阻典型值 4.7 kΩ 2.2 kΩ 1.0 kΩ

注意:总线电容包括所有设备的引脚电容、PCB走线寄生电容、连接器电容。电容太大,上拉电阻就得选小一点,否则上升沿太缓,时序会出问题。我曾经在一块长排线上挂了8个传感器,400kHz死活跑不起来,换1kΩ上拉电阻才搞定。

1.3 开漏输出与上拉电阻:选多大才合适?

上拉电阻的取值是个权衡。太小了,灌电流太大,功耗高,而且IO口可能扛不住。太大了,上升沿太慢,高速模式跑不动。

计算公式很简单:

R_pullup_min = (V_cc - V_OL_max) / I_OL_max
R_pullup_max = t_r / (0.8473 × C_bus)

其中:

  • V_cc:总线供电电压(通常是3.3V或5V)
  • V_OL_max:输出低电平最大值(标准0.4V)
  • I_OL_max:IO口灌电流能力(通常3-20mA)
  • t_r:允许的上升时间(100kHz时1000ns,400kHz时300ns)
  • C_bus:总线总电容

我的经验值:3.3V系统、2-3个从机、PCB走线不长,直接上4.7kΩ。如果从机多、线长、或者跑400kHz,换成2.2kΩ。高速模式(3.4MHz)必须用1kΩ以下,而且PCB布局要非常讲究。

1.4 总线拓扑结构图

下面这张图展示了典型的I2C单主机多从机拓扑。注意看SCL和SDA两根线,每个设备都是开漏输出,两根线各有一个上拉电阻到VCC。

I2C总线拓扑结构图 I2C单主机多从机总线拓扑 VCC (3.3V) Rp SCL Rp SDA SCL SDA 主机 STM32F4 从机1 0x50 (EEPROM) 从机2 0x3C (OLED) 从机3 0x76 (气压计) 开漏输出特性 只能拉低 不能主动拉高 线与逻辑

1.5 实际项目中的避坑指南

讲几个我实际踩过的坑,你们以后遇到了心里有数:

  • 上拉电阻没焊:有一次样板回来,I2C死活不通。量SCL和SDA对地电压,只有0.8V左右。一看原理图,上拉电阻位号是NC。焊上4.7kΩ,立马正常。
  • 总线电容过大:用了一根30cm的杜邦线连传感器,400kHz模式下SDA上升沿明显变缓。示波器一看,上升时间超过500ns。换成2.2kΩ上拉,勉强能用,但最后还是改成了100kHz。
  • 地址冲突:两个传感器芯片型号不同,但地址都是0x48。其中一个地址引脚没接对,导致总线仲裁一直出错。后来用I2C扫描程序才发现有两个设备响应同一个地址。
  • 电平不匹配:STM32是3.3V,挂了一个5V的EEPROM。虽然EEPROM的输入高电平阈值能识别3.3V,但它的输出高电平是5V,直接灌进STM32的IO口。加了一颗电平转换芯片才解决。

重要提醒:调试I2C硬件问题,示波器是必须的。别光靠逻辑分析仪看高低电平,要看上升沿斜率、噪声、毛刺。我习惯先把时钟降到10kHz,确认硬件没问题再往上提频率。

1.6 本章小结