3. I2C协议基础:地址模式与速率等级

I2C协议,说白了就是两根线(SCL时钟、SDA数据)搞定一堆设备通信。我刚开始接触时也觉得简单,但真到调试阶段,地址对不对、速率能不能跑上去,全是坑。这一章咱们就把地基打牢。

3.1 7位地址模式

这是最常用的地址模式。主机发送设备地址时,先发7位地址,再加1位读写标志位(0表示写,1表示读)。总共8位,刚好一个字节。

地址帧结构:

起始条件 → 7位地址 → R/W位 → 从机应答(ACK) → 数据... → 停止条件

举个例子:假设一个温度传感器的7位地址是0x48(二进制1001000)。主机要读取数据时,发送的地址字节就是:

0x48 << 1 | 0x01 = 0x91  (读操作)
0x48 << 1 | 0x00 = 0x90  (写操作)

嗯,这里要注意:数据手册里给的地址通常是7位值,你得自己左移一位再加上R/W位。我见过不少新手直接拿手册地址去发,结果从机死活不应答。

7位地址 写地址(0x??) 读地址(0x??)
0x48 0x90 0x91
0x50 0xA0 0xA1
0x68 0xD0 0xD1

我的习惯:写驱动时直接定义两个宏:I2C_ADDR_WRITE(addr) ((addr) << 1) 和 I2C_ADDR_READ(addr) ((addr) << 1 | 0x01),省得每次手动算。

3.2 10位地址模式

7位地址最多挂112个设备(0x00保留,0x08~0x77可用),有些系统不够用。10位地址模式就来了。

10位地址的发送分两阶段:

  1. 第一个字节:高5位固定为11110,接着是10位地址的高2位,最后是R/W位。
  2. 第二个字节:10位地址的低8位。

举个例子,地址0x2B4(二进制10 1011 0100):

第一个字节: 1111 0 [10] [R/W] = 0xF4 | R/W
第二个字节: 1011 0100 = 0xB4

我曾经踩过的坑:有个项目用了10位地址的音频编解码芯片,我按7位方式发地址,芯片没反应。查了两天才发现是地址模式没切换。大多数MCU的I2C外设需要配置寄存器才能启用10位模式,默认都是7位。

说实话,10位地址在实际产品中并不常见。我做了这么多年,也就碰到过两三次。大部分场景7位地址完全够用。

3.3 标准/快速/高速模式速率

I2C有几种速率模式,你想想看,不同速率的时序要求差别挺大。

模式 最大速率 SCL高电平最小宽度 SCL低电平最小宽度 适用场景
标准模式 (Sm) 100 kbit/s 4.0 μs 4.7 μs 温湿度传感器、EEPROM
快速模式 (Fm) 400 kbit/s 0.6 μs 1.3 μs 加速度计、触摸控制器
高速模式 (Hs) 3.4 Mbit/s 0.16 μs 0.16 μs 图像传感器、高速ADC

标准模式最通用,几乎所有I2C设备都支持。快速模式是主流,我现在大部分项目都跑400kHz。高速模式嘛,对PCB布线要求高,我一般只在必须的场景才用。

速率选择原则:

  • 总线上的所有设备必须支持同一速率模式
  • 总线电容越大,速率上限越低(每增加100pF,速率降一档)
  • 高速模式需要额外的电流源上拉,不是所有MCU都支持

3.4 速率与总线电容的关系

为什么总线电容会影响速率?说白了,I2C是开漏输出,SCL和SDA靠上拉电阻拉高。电容越大,信号上升沿越慢,速率就上不去。

我有个经验公式:

最大速率 ≈ 0.847 / (R_pullup × C_bus)

其中:
R_pullup = 上拉电阻值(Ω)
C_bus = 总线总电容(F)

举个例子,总线电容200pF,上拉电阻4.7kΩ:

最大速率 ≈ 0.847 / (4700 × 200 × 10^-12) ≈ 901 kHz

理论上能跑900kHz,但实际我建议留50%余量,设到400kHz比较稳妥。

我的调试经验:如果I2C在高速下通信不稳定,先别急着改软件。拿示波器看SCL的上升沿,如果超过1μs还没到高电平,那就是电容太大或者上拉电阻太大。我一般先换小一点的上拉电阻试试,比如从4.7kΩ换成2.2kΩ。

3.5 知识结构图

下面这张图把I2C地址模式和速率的关系梳理清楚了:

I2C协议基础:地址模式与速率等级 地址模式 7位地址 10位地址 最多112个设备 最多1024个设备 速率等级 标准模式 快速模式 高速模式 100 kbit/s 400 kbit/s 3.4 Mbit/s 影响因素:总线电容、上拉电阻、从机支持能力

3.6 速率选择实战建议

我个人做项目时,速率选择遵循这个原则:

  • 原型验证阶段:先跑100kHz,确保通信没问题
  • 性能优化阶段:逐步提升到400kHz,每次改完跑24小时稳定性测试
  • 量产阶段:根据最差情况(长走线、高温、低电压)确定最终速率

注意:不要为了追求速率而忽略时序容差。我曾经在一个项目里把I2C跑到800kHz(快速模式上限是400kHz),当时测试没问题,结果量产一批货在高温下全部通信失败。后来老老实实降到400kHz,再也没出过问题。