3. I2C地址机制:7位地址与10位地址、广播地址、保留地址

I2C总线上挂多个设备,怎么区分谁是谁?靠的就是地址。说白了,地址就是每个从机的“身份证号”。主机发数据前,先喊一声这个号,对应的从机应答,其他从机保持沉默。

我刚开始学I2C时,总觉得地址这块有点绕。7位、10位、广播、保留……名字听着挺唬人。其实拆开看,没那么复杂。咱们一个一个说。

3.1 7位地址:最常用的方案

标准I2C设备,绝大多数都用7位地址。地址范围从0x00到0x7F,一共128个。但注意,不是所有都能用——有些被保留了。

7位地址怎么用?主机在起始条件后,先发一个字节:高7位是地址,最低位是读写方向(0=写,1=读)。

// 7位地址格式示例
// 假设从机地址为 0x3C(7位)
// 主机要写数据:发送 0x3C << 1 | 0 = 0x78
// 主机要读数据:发送 0x3C << 1 | 1 = 0x79

我遇到过不少新手,直接把7位地址当8位发,结果从机死活不应答。嗯,这里要注意:STM32的I2C外设,有些库函数要你传7位地址,有些要传左移后的8位。看手册,别想当然。

地址位数 范围 可用数量 常见场景
7位 0x00 ~ 0x7F 112(扣除保留地址) 绝大多数传感器、EEPROM、ADC/DAC
10位 0x000 ~ 0x3FF 1024 需要大量从机的复杂系统

3.2 10位地址:什么时候用?

7位地址只有112个可用,有些大系统不够用。I2C规范就扩展了10位地址模式。说实话,我在实际项目中几乎没用过10位地址——大部分场景7位足够了。

10位地址的传输分两步:

  1. 第一个字节:高5位固定为11110,接着是地址的高2位,最后是读写位。
  2. 第二个字节:地址的低8位。
// 10位地址传输示例
// 假设从机10位地址为 0x02C4
// 第一步:发送 11110 + 地址[9:8] + R/W
//         11110 00 0 = 0xF0(写操作)
// 第二步:发送地址低8位 0xC4
我的建议:除非你确定从机支持10位地址,否则别用。很多廉价传感器根本不支持。选型时看一眼数据手册的“Slave Address”章节,一目了然。

3.3 广播地址:喊一嗓子,全员响应

广播地址是0x00。主机发这个地址,所有从机理论上都应该应答。有什么用?

  • 系统同步:让所有从机同时执行某个操作。
  • 地址分配:某些可编程地址的从机,通过广播接收新地址。
  • 复位指令:让所有从机回到初始状态。

我曾经在一个多传感器采集板上用过广播复位。20个传感器挂同一条总线,一个一个复位太慢。发一次广播地址+复位命令,所有传感器同时复位,省事多了。

注意:不是所有从机都响应广播地址。有些从机设计上就忽略0x00。用之前,先确认数据手册里有没有提到“General Call”支持。

3.4 保留地址:这些别碰

I2C规范保留了一些特殊地址,用于特定功能。普通设备不能用这些地址,否则会冲突。

地址(7位) 用途 说明
0x00 广播地址 通用呼叫,所有从机应答
0x01 起始字节 用于慢速设备检测总线
0x02 CBUS地址 兼容旧CBUS协议
0x03 ~ 0x07 保留 未来扩展用
0x78 ~ 0x7B 10位地址前缀 用于10位地址模式
0x7C ~ 0x7F 保留 测试/特殊模式

你看,0x78到0x7B这4个地址,就是10位地址的前缀标志。如果你用7位地址,千万别选这个范围,否则会跟10位设备打架。

3.5 地址冲突:我踩过的坑

说个真实经历。有次做项目,用了两个同样型号的温湿度传感器,地址都是0x44。挂同一条I2C总线上,结果两个传感器互相干扰,数据全乱套。

解决办法有几个:

  • 换地址引脚:很多传感器有ADDR引脚,拉高拉低能换地址。
  • 加I2C多路复用器:比如TCA9548A,分时选通不同通道。
  • 用软件模拟:每个传感器单独用GPIO模拟I2C,但占用引脚多。

我个人习惯,画原理图前先把所有I2C设备的地址列个表,确认没有冲突。省得板子打回来再飞线,那叫一个痛苦。

3.6 地址机制全景图

下面这张图,把I2C地址的整个体系串起来了。从7位到10位,从广播到保留,一目了然。

I2C地址机制全景图 I2C地址体系 7位地址 (0x00~0x7F) 10位地址 (0x000~0x3FF) 广播地址 保留地址 两步传输 前缀标志 关键说明 • 7位地址:最常用,范围0x00~0x7F,可用112个 • 10位地址:扩展方案,分两步传输,兼容7位总线 • 广播地址(0x00):所有从机应答,用于同步/复位 • 保留地址:0x01~0x07、0x78~0x7F,普通设备别用 • 地址冲突:同一条总线不能有两个相同地址的从机 • 选型建议:先查数据手册,确认地址范围和是否支持10位

3.7 实战建议:地址怎么选?

最后,给几个实在的建议:

  • 优先用7位地址:兼容性好,代码简单。
  • 避开保留地址:0x00~0x07、0x78~0x7F别碰。
  • 画原理图前列表:把所有I2C设备的地址写出来,确认没冲突。
  • 留好ADDR引脚:如果传感器有地址选择引脚,拉到VCC或GND,别悬空。
  • 读数据手册:每个设备的地址范围和支持模式,手册里写得清清楚楚。