1. I2C总线协议基础:物理层特性、电气特性、总线拓扑结构、I2C与SPI/UART的对比
各位同学,咱们今天正式开讲I2C总线。说实话,我做了十几年嵌入式开发,跟各种总线打过交道,但I2C始终是我最常用的总线之一。为什么?因为它简单、灵活,而且占用的引脚极少。你想想看,只用两根线就能挂载几十个设备,这在寸土寸金的PCB板上简直是福音。
1.1 物理层特性
I2C总线物理层其实就两条线:SDA(串行数据线)和SCL(串行时钟线)。这两条线都是双向的,采用开漏(Open-Drain)结构。什么叫开漏?说白了就是芯片只能把线拉低,不能主动拉高。那高电平谁来提供?靠上拉电阻。
核心要点:I2C总线的SDA和SCL都是开漏输出,必须外接上拉电阻才能正常工作。上拉电阻的阻值选择直接影响总线速度和功耗。
我记得刚入行那会儿,有个项目死活调不通I2C,波形乱七八糟。查了半天,发现是上拉电阻选得太大了,导致信号上升沿太慢。嗯,从那以后我选上拉电阻就特别小心。
1.2 电气特性
I2C的电气特性有几个关键参数,我列个表给大家看:
| 参数 | 标准模式 (100kHz) | 快速模式 (400kHz) | 高速模式 (3.4MHz) |
|---|---|---|---|
| 最大时钟频率 | 100 kHz | 400 kHz | 3.4 MHz |
| 逻辑低电平 (VIL) | 0.3 × VDD | 0.3 × VDD | 0.3 × VDD |
| 逻辑高电平 (VIH) | 0.7 × VDD | 0.7 × VDD | 0.7 × VDD |
| 最大总线电容 | 400 pF | 400 pF | 100 pF |
| 上拉电阻推荐值 | 4.7kΩ - 10kΩ | 1.5kΩ - 4.7kΩ | 0.5kΩ - 1.5kΩ |
避坑指南:我曾经在一个项目中,把3.3V和5V的I2C设备混接在同一总线上,结果通信时好时坏。后来才发现,不同电压域的设备需要加电平转换芯片,或者使用支持多电压的I2C总线缓冲器。千万别图省事直接连!
1.3 总线拓扑结构
I2C总线采用多主从拓扑结构。什么意思?就是总线上可以有多个主设备,每个主设备都能发起通信。但同一时刻只能有一个主设备控制总线,这就涉及到总线仲裁机制。
我画了一张I2C总线拓扑结构图,大家看看:
从图上可以看到,所有设备都挂在同一条SDA和SCL线上。每个从设备都有一个唯一的地址,主设备通过地址来选择要通信的设备。我习惯把I2C总线想象成一条电话线——主设备是打电话的人,从设备是接电话的人,地址就是电话号码。
1.4 I2C与SPI/UART的对比
做嵌入式开发,这三类总线你肯定都会遇到。我根据自己的经验,给大家做个对比:
| 特性 | I2C | SPI | UART |
|---|---|---|---|
| 信号线数量 | 2 (SDA, SCL) | 4 (MOSI, MISO, SCLK, CS) | 2 (TX, RX) |
| 通信方式 | 半双工 | 全双工 | 全双工 |
| 同步/异步 | 同步 | 同步 | 异步 |
| 最大设备数 | 理论128个 (7位地址) | 受限于CS引脚数 | 点对点 |
| 典型速率 | 100kHz - 3.4MHz | 10MHz - 100MHz | 9600bps - 1Mbps |
| 硬件复杂度 | 低 (开漏+上拉) | 中 (推挽输出) | 低 (推挽输出) |
| 适用场景 | 传感器、EEPROM、RTC | 高速ADC/DAC、LCD、SD卡 | GPS、蓝牙、串口调试 |
我的选择建议:如果你要挂载多个传感器,而且对速度要求不高,I2C是首选。我做过一个项目,一块板子上挂了6个传感器,只用2根线就搞定了。要是用SPI,光片选线就得6根,布线会非常痛苦。
为什么会这样?我给大家分析一下:
- I2C:用地址来区分设备,所以线少。但每次通信都要先发地址,有协议开销,速度上不去。
- SPI:用片选线来选设备,线多但速度快。全双工通信,适合大数据量传输。
- UART:最简单,但只能点对点。没有时钟线,靠波特率同步,容易受干扰。
我记得有一次调试一个传感器模块,用I2C怎么都读不到数据。后来换SPI试了一下,一次就成功了。查了半天,发现是I2C地址搞错了——那个传感器的地址手册上写的是7位,但我按8位去发了。嗯,这种坑踩过一次就记住了。
总结一下:I2C适合多设备、低速、短距离的场景;SPI适合高速、大数据量的场景;UART适合点对点、简单通信的场景。选型时根据实际需求来,没有绝对的好坏。