1. I2C协议基础:从一根线到两根线的故事

各位同学,咱们今天聊聊I2C。这玩意儿在嵌入式开发里太常见了——传感器、EEPROM、ADC、显示屏,十有八九都用它。我刚开始学单片机那会儿,总觉得I2C挺玄乎,两根线就能挂一堆设备,怎么做到的?后来踩了几个坑,才真正搞明白。

说白了,I2C就是飞利浦(现在叫NXP)在80年代搞出来的一种串行通信总线。它只靠两根线——SDA(数据线)和SCL(时钟线)——就能让主设备和从设备之间传数据。你想想看,要是用并行总线,8位数据就得8根线,再加控制信号,板子上全是飞线,多头疼。

核心要点:I2C是同步、半双工、多主从的串行总线。两根线搞定一切。

1.1 物理层特性:开漏输出与上拉电阻

先看物理层。SDA和SCL都是开漏输出结构。什么叫开漏?就是MOS管的漏极直接接到引脚上,没有内部上拉。输出低电平时,管子导通,引脚拉低;输出高电平时,管子截止,引脚悬空。

嗯,这里要注意——悬空的状态是不确定的。所以必须在外部接上拉电阻,把引脚拉到高电平。这样总线空闲时,SDA和SCL都是高电平。

我个人习惯:4.7kΩ上拉电阻是万金油,100kHz标准模式基本都能用。如果总线电容大(线长、设备多),换成2.2kΩ;如果追求低功耗,可以试试10kΩ。但别超过10kΩ,否则上升沿太慢,波形会变“圆”。

开漏结构有个好处:线与。多个设备可以同时拉低总线,不会短路。任何一个设备拉低,总线就是低电平。这为后面讲的多主机仲裁打下了基础。

参数 标准模式 (100kHz) 快速模式 (400kHz) 高速模式 (3.4MHz)
上拉电阻典型值 4.7kΩ 2.2kΩ 1kΩ 或更小
总线电容上限 400pF 400pF 100pF
上升时间 ≤1000ns ≤300ns ≤120ns

我在项目里遇到过一件事:一块板子上挂了8个I2C设备,线长大概30cm,用4.7kΩ上拉,400kHz模式下SCL波形上升沿明显变缓,偶尔通信失败。换成2.2kΩ后,波形干净了,问题解决。所以,上拉电阻不是随便选的,得根据总线负载算一下。

1.2 协议层:起始、停止、数据与应答

物理层搞明白了,咱们看协议层。I2C的协议其实就四个核心动作:起始条件、停止条件、数据传送、应答机制。把这四个搞懂,I2C通信你就掌握了八成。

1.2.1 起始条件 (START)

SCL为高电平时,SDA从高电平跳变到低电平。这就是起始条件。

为什么要这么设计?因为SCL高电平时,SDA本应稳定不变。SDA突然变低,就是一个“特殊信号”,告诉所有从设备:注意,要开始传数据了。

我曾经踩过的坑:在STM32上用GPIO模拟I2C时,起始条件的时序没卡好——SCL拉高后,SDA拉低的保持时间太短。结果从设备根本没识别到起始信号,后续所有数据都白传。后来用示波器一看,SDA下降沿离SCL上升沿才几十纳秒,根本不够。标准模式要求至少4.7μs的建立时间。

1.2.2 停止条件 (STOP)

SCL为高电平时,SDA从低电平跳变到高电平。这就是停止条件。

跟起始条件正好相反。从设备检测到这个信号,就知道本次传输结束了,可以释放总线。

1.2.3 数据有效性

数据怎么传?规则很简单:

  • SCL为高电平时,SDA上的数据必须稳定(不能变化)
  • SCL为低电平时,SDA可以变化(准备下一位数据)

说白了,SCL高电平是“采样窗口”,SCL低电平是“数据切换窗口”。每个SCL时钟脉冲传1位数据,先传最高位(MSB),再传低位。

你想想看,如果SCL高电平时SDA还在跳变,接收方该采样哪个电平?所以这个规则保证了数据采样的确定性。

1.2.4 应答机制 (ACK/NACK)

每传完8位数据(一个字节),第9个SCL时钟周期就是应答位。

  • ACK (应答):接收方在第9个时钟周期拉低SDA,表示“收到,请继续”
  • NACK (非应答):接收方在第9个时钟周期保持SDA高电平,表示“别再发了”或“我没准备好”

应答机制是I2C可靠性的关键。发送方每发一个字节,都要等接收方回应。如果收到NACK,发送方就知道出问题了——要么地址不对,要么从设备忙,要么传输结束。

实战经验:调试I2C设备时,第一个要看的信号就是应答位。如果从设备地址发出去后,第9个时钟SDA还是高电平,说明从设备没响应。这时候别急着查代码,先量一下从设备的供电和上拉电阻。

1.3 完整数据传输流程

把上面四个动作串起来,一次完整的I2C写操作是这样的:

  1. 主设备发送起始条件
  2. 主设备发送7位从设备地址 + 1位读写位(0表示写)
  3. 从设备回复ACK
  4. 主设备发送1字节寄存器地址
  5. 从设备回复ACK
  6. 主设备发送1字节数据
  7. 从设备回复ACK
  8. ……(可以继续发更多数据)
  9. 主设备发送停止条件

读操作类似,只是读写位改成1,而且最后主设备要发NACK告诉从设备“别发了”。

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

下面这张图把I2C协议的核心要素串起来了。你可以把它当作本章的“思维导图”。

I2C协议知识结构图 I2C 总线协议 物理层特性 协议层规则 开漏输出 上拉电阻 起始/停止 数据有效性 应答机制 两根线(SDA + SCL) 半双工同步通信 · 多主从架构 · 线与逻辑 START 地址+读写 ACK 数据字节 STOP 一次完整的I2C写操作流程(7位地址模式)

1.5 本章小结

I2C协议的基础就这些。总结一下:

  • 物理层:开漏输出 + 上拉电阻,实现线与逻辑
  • 起始/停止:SCL高电平时SDA的跳变沿,是通信的“开始”和“结束”信号
  • 数据有效性:SCL高电平采样,SCL低电平切换,MSB先行
  • 应答机制:第9个时钟,ACK表示继续,NACK表示停止