Skip to main content

通讯协议-IIC

I²C(Inter-Integrated Circuit,也常写作 IIC)是一种两线、同步、支持多控制器和多目标设备的串行总线。它常用于 MCU 与传感器、EEPROM、电源管理芯片、时钟芯片等低速外设之间的板级通信。

信号线与电气特性

信号作用
SCL串行时钟线
SDA双向串行数据线
GND通信双方的参考地

SCL 和 SDA 通常采用开漏/开集电极结构。设备只能主动拉低总线,高电平由上拉电阻产生。这种结构允许多个设备共享总线,并支持应答、仲裁和时钟延展。

VDD ── 上拉电阻 ── SCL ── 控制器与各目标设备
VDD ── 上拉电阻 ── SDA ── 控制器与各目标设备
GND ─────────────── GND ── 所有设备共地

上拉电阻需要结合电源电压、总线电容、目标速率和器件灌电流能力选择。电阻过大时上升沿过慢,过小时低电平电流过大。

基本时序

总线空闲时,SCL 和 SDA 均为高电平。

条件定义
START(起始)SCL 为高时,SDA 从高变低
STOP(停止)SCL 为高时,SDA 从低变高
数据有效SCL 为高期间,SDA 保持稳定
数据改变通常在 SCL 为低期间改变 SDA
Repeated START不先发送 STOP,直接再次发送 START

每个数据字节通常先传输最高有效位(MSB),随后是第 9 个时钟周期的 ACK/NACK。

地址与读写位

常见 I²C 使用 7 位设备地址。线上发送的第一个字节由 7 位地址和 1 位读写方向位组成:

bit7                      bit1  bit0
7 位设备地址 R/W
R/W 位方向
0控制器写入目标设备
1控制器读取目标设备
7 位地址与“8 位地址”

器件手册或旧代码有时会把“7 位地址左移一位并附加 R/W 位”写成两个 8 位地址。例如,7 位地址 0x50 的写地址字节是 0xA0,读地址字节是 0xA1。配置 MCU 驱动前,应确认 API 接收的是 7 位地址还是已经移位的地址字节。

I²C 也定义了 10 位地址格式,但常见外设大多使用 7 位地址。

ACK 与 NACK

发送方发送 8 位数据后释放 SDA,接收方在第 9 个时钟周期回应:

应答SDA 状态含义
ACK拉低已接收该字节,可以继续
NACK保持高未接收、无法继续,或读取已结束

控制器读取多个字节时,通常对中间字节发送 ACK,对最后一个字节发送 NACK,然后发送 STOP。

常见传输流程

写寄存器

START → 地址+W → ACK → 寄存器地址 → ACK → 数据 → ACK → STOP

读寄存器

许多寄存器型设备先通过写操作选择寄存器,再使用重复起始切换为读取:

START → 地址+W → ACK → 寄存器地址 → ACK
Repeated START → 地址+R → ACK → 数据 → NACK → STOP

具体设备是否支持地址自增、寄存器地址长度和连续读写,必须以器件手册为准。

常见速率

模式标称最高速率说明
Standard-mode100 kbit/s常用基础模式
Fast-mode400 kbit/s常见高速模式
Fast-mode Plus1 Mbit/s对上拉、总线电容与器件能力要求更高
High-speed mode3.4 Mbit/s需要兼容设备和对应时序

实际可用速率受到总线电容、走线、上拉电阻、器件能力和电平转换器影响。

时钟延展与仲裁

目标设备在需要更多处理时间时,可将 SCL 保持为低电平,让控制器等待,这称为时钟延展。控制器和中间电平转换器必须支持该行为。

多控制器同时发起传输时,通过 SDA 仲裁决定谁继续占用总线。控制器发送高电平却读到低电平时,应认定仲裁丢失并停止发送。单控制器系统通常不会用到仲裁,但驱动仍可能提供对应状态标志。

优点与限制

优点限制
仅需两根信号线,可连接多个设备上拉结构限制速度和总线电容
原生地址与逐字节应答无原生 CRC,错误检测能力有限
支持多控制器、仲裁与时钟延展地址冲突需要改地址、复位控制或总线复用器
器件和 MCU 支持广泛不适合长距离和强干扰环境

常见问题与排查

现象常见原因排查方法
SCL/SDA 始终为低器件未释放总线、短路、掉电器件反向供电逐个断开设备,检查电源和引脚状态
地址无 ACK地址格式错误、设备未供电、复位未释放扫描 7 位地址并核对器件地址脚
低速正常,高速失败上升沿过慢、总线电容大、上拉不合适示波器测量上升沿,调整上拉或降低速率
读取数据错位寄存器地址长度、重复起始或字节序错误对照手册检查完整事务
偶发总线锁死传输中复位,目标设备等待剩余时钟实现总线恢复并复位 I²C 外设
多设备无法共存设备地址冲突修改地址脚,分时复位或增加总线复用器

总线恢复

若控制器复位时目标设备正处于发送过程,目标设备可能持续拉低 SDA。常见恢复思路是:

  1. 暂时将 SCL/SDA 配置为开漏 GPIO。
  2. 在 SDA 被拉低时,向 SCL 输出若干时钟脉冲,让目标设备完成当前字节。
  3. 产生 STOP 条件。
  4. 重新初始化 I²C 外设。

所需脉冲数量和恢复行为应结合目标器件手册验证;并非所有器件都支持同样的恢复方式。

调试步骤

  1. 确认电压等级、公共地和上拉电阻存在。
  2. 空闲时测量 SCL 与 SDA,二者应为高电平。
  3. 用逻辑分析仪确认 START、地址、R/W 位和 ACK/NACK。
  4. 明确驱动 API 使用 7 位地址还是地址字节。
  5. 对照器件手册检查寄存器地址长度、重复起始和读写顺序。
  6. 高速或不稳定时,用示波器检查上升沿、低电平和振铃。

适用场景

I²C 适合板内多个低速外设共享总线。对高速连续数据可考虑 SPI;对长距离、强干扰或多节点可靠通信可考虑 CAN、RS-485 等接口。

相关文档