第一讲:I2C总线协议基础 —— 历史、特点与电气特性
各位同学好,我是你们的老王。做了这么多年嵌入式,调试过最多的接口就是 I2C。每次遇到时钟拉伸问题,很多工程师就抓瞎。其实基本功打牢了,这些坑根本绕不过你。我们从头捋一遍 I2C 的底子,后面几章才能砸得实。
1.1 从一根「总线」的诞生说起
1982 年,飞利浦半导体(现在的 NXP)搞出了 I2C。干嘛用的?给电视机里的微控制器和外围芯片之间连根简单的串行线。先别笑,那时电视机里的线比你家路由器还乱。
我之前拆过一台老款飞利浦彩电,里面好几块 IC 挂在一条两线上。人家当时的想法很朴素:用最少的引脚把多个芯片串起来。
- 名称:Inter-Integrated Circuit,也叫 I²C 或 I2C。
- 诞生年份:1982 年,1992 年推出 400kbps 快速模式(Fast-mode),后来还有 1MHz 快速+ 和 3.4MHz 高速模式。
- 核心思想:两条线——SDA(数据线)和 SCL(时钟线)。
- 多主多从:总线可以挂多个主机和多个从机,谁先拉低时钟谁就是主角。
一个小踩坑:我当年给一块传感器芯片挂总线,一上电就卡死。查了半天发现是地址冲突——两个从机用了同一个7位地址。I2C 地址只7位(或10位),同一总线上不能重名。
1.2 I2C 的独门绝技
跟 SPI、UART 比起来,I2C 有几个硬核特点。你记住下面这张表,面试和排错都用得上。
| 特性 | I2C | SPI | UART |
|---|---|---|---|
| 线数 | 2(SDA + SCL) | 3-4(SCK, MOSI, MISO, SS) | 2(TX, RX) |
| 主从数量 | 多主多从,用地址寻址 | 一主多从,用片选线 | 点对点 |
| 时钟 | 由主机产生,从机可拉低(时钟拉伸!) | 主机产生,从机被动接收 | 异步,无时钟线 |
| 传输速率 | 标准 100kbps,快速 400kbps,高速 3.4Mbps | 几 Mbps 到几十 Mbps | 常见 115200bps,可到数 Mbps |
| 总线仲裁 | 硬件内置,冲突检测 | 无,需软件处理 | 无 |
看到“时钟拉伸”这四个字了吗?这就是我们整门课的主角。I2C 允许从机在收到数据后,主动把 SCL 线拉低,意思是“我还没处理好,你别给时钟了”。主机看到 SCL 拉低,只能等,一直等到从机松开。
小心!很多 MCU 的 I2C 外设在硬件上不支持时钟拉伸,一旦碰到就会产生超时错误。我曾在 STM32F103 上踩过这个坑——从机是 EEPROM,写入需要几毫秒,它拉低 SCL 等写入完成,结果主机直接超时报错,数据全丢了。
1.3 电气特性:再讲一遍,不能再忘了
咱们不背手册,就记几个关键点。
- 开漏输出:SDA 和 SCL 都是开漏(open-drain)结构。芯片只能拉低到 GND,不能主动拉高。高电平靠上拉电阻拉到 VDD。
- 上拉电阻怎么选? 总线电容越大,电阻就得越小,否则上升沿太慢。标准模式下 4.7kΩ 常用,快速模式下 1.5-2.2kΩ。总线长度超过 10cm 或挂的设备超过 5 个,电阻要减小。
- 电平兼容:不同 VDD 的设备可以直接连?不一定。如果从机是 3.3V,主机是 5V,必须在 SDA/SCL 上加电平转换器。当然,很多芯片宣称“容限”,但别信手册上的“5V tolerant”,实际接上去可能烧引脚。
- 最大总线电容:标准模式下限 400pF,快速模式下 200pF。超过这个值,上升沿会变成钝角梯形,通信直接废掉。
一个重要判断:总线空闲时,SDA 和 SCL 都是高电平(上拉电阻拉高)。如果你量到 SDA 或 SCL 一直低,说明有设备在拉总线,或者上拉电阻没焊。
1.4 I2C 协议的基本骨架
有了电气基础,我们再走一遍通信流程。下面这张 SVG 图把一次 I2C 从写数据到读数据的完整过程画出来了。你以后调试时,可以在逻辑分析仪上对照着看。
上面这张图涵盖了从起始到停止的完整流程。注意中间那个“时钟拉伸”说明框——从机在 ACK 之后或者每个字节传输完之后,都可能把 SCL 拉低。主机如果没做超时处理,整个总线就会挂死。
1.5 我自己的实战笔记:电气上的几个“魔鬼细节”
- 上拉电阻别迷信公式:计算公式是 Rmin = (VDD - 0.4V) / 3mA,Rmax = t_r / (0.8473 * C_bus)。我习惯先焊 4.7kΩ,然后拿示波器看上升沿。如果上升沿超过 SCL 周期的 30%,换小电阻。
- 总线长度 vs 电容:双绞线每米约 100pF。如果你的线长 1 米,别想再挂 8 个从机。每加一个器件,总电容会增加 5-15pF。我有一次在产品上挂了 12 个传感器,总线电容直接爆表,调试了一周才发现。
- 电平转换的坑:我早期用分立 MOSFET 搭电平转换,结果上升沿毛刺尖峰一大堆。最后老老实实买专用芯片(如 PCA9306)。省那几毛钱,不值得。
一个检测小技巧:用逻辑分析仪抓一组 I2C 波形,先看 SCL 高电平的平稳性。如果 SCL 低电平时间忽长忽短,八成是时钟拉伸事件,再深挖那个从机为什么会拉低。
1.6 本章小结——记住这几条“铁律”
- I2C 是开漏总线,两线上拉至 VDD,空闲为高。
- 时钟拉伸是从机合法的“慢点处理”信号,但很多主机不支持,导致超时。
- 地址冲突、总线电容超标、上拉电阻不对,是前三名“隐形杀手”。
好了,第一讲的基础就这么多。下一节课我们会把时钟拉伸的底层机制彻底解剖开——包括从机在什么时候拉、拉多长时间、主机应该怎么等。你自己先拿示波器抓几组波形,我们课上对答案。
嗯,就这样。有什么问题翻翻前面的 SVG,或者直接群里喊我。