1. I2C协议基础:从一根线说起

各位同学,咱们今天聊I2C。这玩意儿在嵌入式圈子里太常见了——LCD屏幕、传感器、EEPROM,十有八九都靠它通信。我最早接触I2C是在一个温湿度采集项目上,当时觉得“两根线就能传数据?这也太省了吧”。后来踩了不少坑,才真正摸透它的脾气。

1.1 I2C总线的起源

I2C(Inter-Integrated Circuit)是飞利浦(现恩智浦)在1982年推出的。初衷很简单:让芯片之间用最少的线连起来。你想啊,如果每个外设都单独拉一组数据线、地址线、控制线,那PCB上得乱成什么样?

所以I2C只用了两根线:

  • SDA(Serial Data Line)—— 数据线
  • SCL(Serial Clock Line)—— 时钟线

所有设备都挂在这两根线上,通过地址区分谁跟谁说话。说白了,就像一条电话总线,每个设备有自己的号码。

核心思想:主设备(通常是MCU)控制时钟,发起通信;从设备(LCD、传感器等)响应地址,接收或发送数据。同一时刻只能有一个主设备说话。

1.2 物理层特性:SDA与SCL

这两根线都是开漏输出结构。什么叫开漏?就是引脚只能拉低到GND,不能主动输出高电平。那高电平谁来给?上拉电阻。

我习惯用4.7kΩ的上拉电阻,5V系统用10kΩ也行。如果线长或者设备多,可以换2.2kΩ。嗯,这里有个坑——上拉电阻太小,功耗大;太大,信号上升沿变慢,高速通信容易出错。我曾经在一个项目里用了100kΩ的上拉,结果400kHz模式下数据全是乱的,查了两天才发现是电阻选大了。

参数 典型值 说明
上拉电阻 2.2kΩ ~ 10kΩ 取决于总线电容和速率
总线电容 ≤ 400pF 标准模式下限制
高电平输入阈值 ≥ 0.7 × VDD 不同电压域需注意
低电平输入阈值 ≤ 0.3 × VDD 噪声容限

注意:如果主设备和从设备工作在不同电压(比如3.3V的MCU驱动5V的LCD),必须做电平转换。直接用IO口硬怼,轻则通信异常,重则烧芯片。我见过不止一次这样的案例。

1.3 I2C通信速率标准

I2C的速率分几个档,别搞混了:

  • 标准模式(Standard Mode):100 kbit/s。最常用,兼容性最好。
  • 快速模式(Fast Mode):400 kbit/s。大部分LCD和传感器都支持。
  • 高速模式(High-Speed Mode):3.4 Mbit/s。需要特殊硬件支持,普通MCU不一定有。
  • 超快速模式(Ultra Fast Mode):5 Mbit/s。单向传输,用得少。

我个人建议:调试阶段先用100kHz。为什么?低速下信号完整性好,逻辑分析仪抓波形也容易看。等通信稳定了,再慢慢提速度。我曾经一上来就开400kHz,结果LCD花屏,排查半天发现是走线太长导致信号反射。

小技巧:用示波器看SDA和SCL的上升沿。如果上升沿太缓(超过1μs),说明上拉电阻太大或者总线电容太高。这时候要么换小电阻,要么降速率。

1.4 知识结构图:I2C协议全景

下面这张图帮你理清I2C协议的核心脉络。从物理层到应用层,每个环节都有对应的知识点。

I2C协议知识结构图 I2C协议知识结构 I2C 总线 物理层特性 通信协议 速率标准 SDA / SCL 开漏输出 + 上拉 起始 / 停止条件 地址 + 读写位 100k / 400k / 3.4M 应用层:LCD驱动、传感器读取、EEPROM读写 说明:物理层决定“怎么传”,协议层决定“传什么”,速率决定“传多快” 三者缺一不可,任何一个环节出问题,LCD都不会正常工作 本章重点:打好I2C基础,后续调试不慌

1.5 避坑指南:我踩过的那些I2C坑

做硬件调试这么多年,I2C相关的故障我见过不少。挑几个典型的说说:

  • 总线死锁:从设备拉低SDA不放,主设备等不到释放。解决办法——给SCL发9个时钟脉冲,让从设备复位状态机。
  • 地址冲突:两个设备用了同一个地址。LCD的I2C地址通常是0x27或0x3F,买模块前先确认。
  • 电平不匹配:3.3V主控接5V LCD,没做电平转换。结果通信时好时坏,摸不着头脑。
  • 上拉电阻缺失:有些开发板没焊上拉电阻,SDA和SCL浮空,数据根本传不过去。

我的经验:调试I2C设备,第一步永远是用逻辑分析仪抓波形。看起始条件、地址、ACK位,一眼就能判断问题出在哪。别上来就改代码,先看硬件。