1. I2C协议基础:从一根线上看通信本质
大家好,我是你们的嵌入式讲师。今天咱们开始第一讲——I2C协议基础。说实话,I2C是我在项目里打交道最多的总线之一,没有它,很多传感器、存储芯片、显示屏都玩不转。你想想看,两根线就能挂一堆设备,这设计确实巧妙。
1.1 I2C总线起源:飞利浦的“小发明”
I2C(Inter-Integrated Circuit)总线,是飞利浦半导体(现在的NXP)在1982年推出的。初衷很简单——减少芯片之间的连线。当时板级通信要么用并行总线(线多、占面积),要么用UART(点对点,不能多设备)。飞利浦想:能不能用两根线搞定所有外设?于是I2C诞生了。
我个人习惯把I2C看作“公共汽车”——所有设备挂在同一条线上,谁上车谁下车,靠地址识别。这个思想后来影响了SMBus、PMBus等衍生协议。
| 特性 | I2C | SPI | UART |
|---|---|---|---|
| 信号线数量 | 2(SDA + SCL) | 4(MOSI/MISO/SCLK/CS) | 2(TX/RX) |
| 多设备支持 | 是(地址寻址) | 是(片选) | 否(点对点) |
| 通信速率 | 标准100kbps / 快速400kbps | 可达数十Mbps | 取决于波特率 |
| 硬件复杂度 | 低(开漏+上拉) | 中(推挽+片选) | 低 |
1.2 物理层特性:SDA与SCL的“握手”
I2C只有两根线:SDA(串行数据线)和SCL(串行时钟线)。但这两根线的电气特性,决定了整个协议的成败。
1.2.1 开漏输出与线与逻辑
I2C的SDA和SCL都是开漏(Open-Drain)结构。什么意思?说白了,芯片只能把线拉低(输出0),不能主动拉高(输出1)。高电平靠外部上拉电阻实现。
这样做的好处是:多个设备可以同时“拉低”同一根线,不会短路。这就是线与(Wired-AND)逻辑——只要有一个设备拉低,总线就是低电平。
1.2.2 上拉电阻选择:不能大也不能小
上拉电阻是I2C电路里最容易忽略、也最容易出问题的地方。我踩过这个坑——有一次板子焊好,I2C死活不通,示波器一看,SCL上升沿像爬坡一样慢。换小电阻就好了。
上拉电阻的取值取决于三个因素:
- 总线电容:线越长、挂的设备越多,电容越大
- 通信速率:速率越高,上升沿要求越陡
- 驱动能力:芯片拉低时的灌电流有限
| 总线电容 | 标准模式(100kHz) | 快速模式(400kHz) |
|---|---|---|
| ~50pF(短距离,1-2个设备) | 4.7kΩ ~ 10kΩ | 2.2kΩ ~ 4.7kΩ |
| ~100pF(中等距离,3-5个设备) | 2.2kΩ ~ 4.7kΩ | 1kΩ ~ 2.2kΩ |
| ~200pF(较长距离,多个设备) | 1kΩ ~ 2.2kΩ | 680Ω ~ 1kΩ |
1.3 电气特性:电平标准与噪声容限
I2C的电气特性在不同电压域下表现不同。现在主流是3.3V和1.8V系统,但5V的老设备也常见。
| 参数 | 标准模式 | 快速模式 | 快速模式+(1MHz) |
|---|---|---|---|
| VIL(输入低电平) | 0.3 × VDD | 0.3 × VDD | 0.3 × VDD |
| VIH(输入高电平) | 0.7 × VDD | 0.7 × VDD | 0.7 × VDD |
| VOL(输出低电平) | 0.4V @ 3mA | 0.4V @ 3mA | 0.4V @ 3mA |
| 最大上升时间 | 1000ns | 300ns | 120ns |
嗯,这里要注意:不同电压的设备混接时,必须保证高电平阈值兼容。3.3V主控接5V从设备,如果从设备的VIH是0.7×5V=3.5V,那3.3V的高电平就够不到了。我建议用电平转换芯片,或者选支持宽电压的器件。
1.4 知识体系总览
下面这张图把I2C物理层的核心知识点串起来了。你看一遍,心里就有谱了。
1.5 实战经验:上拉电阻选型三步走
我总结了一个上拉电阻选型的实用流程,你在项目里可以直接套用:
- 估算总线电容:每厘米PCB走线约1pF,每个设备引脚约5-10pF。比如10cm走线+4个设备,大约10+40=50pF。
- 查表选初值:根据电容和速率,从上表选一个中间值。比如50pF、400kHz,选2.2kΩ。
- 示波器验证:测SCL上升沿,确保不超过规格(400kHz要求<300ns)。如果上升沿太缓,换小电阻;如果波形有过冲,换大电阻。