📚 I2C 技术系列 · 持续更新中
本系列从 OD 开漏物理层一路打到 Linux i2c子系统,把"两根线"背后那套电气/协议/仲裁/恢复/驱动全拧成一根线。
👉 想系统追更,戳这里查看完整目录:
【I2C 技术系列 00】总目录
本篇定位:I2C 系列收官篇。把全系列(01-13)的精华浓缩成现场可用的排查手册和速查表——故障决策树、上拉速算、时序参数、错误对照、全系列要点回顾。遇到 I2C 问题,翻这篇,3 分钟定位方向。
这篇是你 I2C 工作的"随身手册"
13 篇理论你不会天天翻,但现场调试时需要快速决策。本篇把所有关键数据/流程/判据汇成一页,打印贴工位,或存手机随时查。
目录
- 一、故障决策树
- 1.1 通用排查主树
- 1.2 A 分支:通信完全不通
- 1.3 B 分支:偶发错误
- 1.4 C 分支:特定错误码
- 1.5 D 分支:总线挂死
- 1.6 E 分支:Linux 框架问题
- 二、常见故障速查表
- 三、上拉电阻速算表
- 3.1 Rp_min(由灌电流限制)
- 3.2 Rp_max(由上升时间限制)
- 3.3 工程推荐值
- 3.4 总线电容 Cb 限制
- 3.5 tr 测量与 Cb 反算
- 四、时序参数速查表
- 4.1 完整时序参数(NXP UM10204)
- 4.2 参数含义
- 4.3 控制器分频
- 五、错误码与寄存器对照表
- 5.1 Linux 错误码
- 5.2 DesignWare ABRT_SOURCE 位
- 5.3 STM32 状态位
- 六、器件地址速查表
- 6.1 常见器件地址
- 6.2 保留地址(勿用)
- 6.3 7bit ↔ 8bit 转换
- 七、现场排查清单
- 7.1 新板 I2C 首次调试清单
- 7.2 故障现场排查清单
- 7.3 功能安全审查清单
- 八、I2C 系列全要点回顾
- 8.1 硬件基础层(01-03)
- 8.2 协议与时序层(04-07)
- 8.3 驱动实现层(08-11)
- 8.4 应用实战层(12-14)
- 8.5 核心数据速记
- 延伸阅读
- 参考资料
一、故障决策树
1.1 通用排查主树
I2C 故障 ↓ 通信完全不通(地址都扫不到) ├─→ [A 分支] 硬件层排查(电源/上拉/焊接/地址) ↓ 通信通但偶发错(数据错/NACK/挂死) ├─→ [B 分支] 信号完整性/时序排查 ↓ 通信通但特定错误(NACK/ARB/TIMEOUT) ├─→ [C 分支] 错误类型定位(查 ABRT_SOURCE) ↓ 总线挂死(BUSY 一直 1) ├─→ [D 分支] 总线恢复(9 时钟/复位) ↓ Linux 驱动层问题(probe 失败/sysfs 没设备) ├─→ [E 分支] Linux 框架排查(dmesg/设备树)1.2 A 分支:通信完全不通
i2cdetect 扫不到 ↓ 1. 万用表测 VDD(器件供电对不对) ├ 不对 → 修电源 ↓ 2. 测 SDA/SCL 静态电平(应 = VDD) ├ 低 → 短路?器件拉低?上拉没接? ↓ 3. 测上拉电阻(SDA-VDD 应 4.7k 左右) ├ 不对 → 焊/换电阻 ↓ 4. 示波器抓 START(发地址时 SDA/SCL 动不动) ├ 不动 → 控制器没输出(pinctrl/时钟/设备树) ├ 动但无 ACK → 器件没响应(地址/焊接/上电) ↓ 5. 确认地址(7bit,引脚配置位 A0/A1/A2) ├ datasheet 0xA0 → 实际 7bit 0x50 ↓ 6. 器件上电时序(慢上电器件要 delay)1.3 B 分支:偶发错误
偶发 NACK / 数据错 / 挂死 ↓ 1. dmesg 看错误类型 ↓ 2. 逻辑分析仪抓偶发时刻 ├ 上升沿缓 → 上拉/电容问题(→ C 节) ├ 毛刺 → EMI(滤波/屏蔽) ├ 拉伸超时 → 从机慢/异常 └ 仲裁丢失(单主不该有)→ 毛刺误识别 ↓ 3. 降速测试(400k→100k) ├ 降速好了 → 信号完整性问题 └ 降速还错 → 协议/器件问题 ↓ 4. 软件加重试 + 错误统计 + 看门狗1.4 C 分支:特定错误码
读 ABRT_SOURCE / dmesg 错误码 ├ NACK(地址) → 器件不在/地址错,不重试 ├ NACK(数据) → 器件异常,STOP+上报 ├ ARB_LOST → 退避+随机延时重试(单主查 EMI) ├ TIMEOUT(拉伸) → 9 时钟恢复 + 复位 ├ BUSY 卡死 → GPIO 读电平 → 9 时钟(→ D 分支) └ 字节错位 → 上层 CRC,重读1.5 D 分支:总线挂死
BUSY=1 长时间 ↓ GPIO 切输入读 SDA/SCL ├ SCL=0, SDA=0 → 从机拉两根 / 严重短路 → 硬件复位 ├ SCL=1, SDA=0 → 从机拉低 SDA(经典)→ 9 时钟恢复 ├ SCL=0, SDA=1 → 从机拉伸 SCL → 超时 + 复位 └ SCL=1, SDA=1 → 控制器假 BUSY → 软件复位 ↓ 9 时钟恢复无效 → 硬件复位从机 ↓ 仍无效 → 标记器件失效,进安全状态1.6 E 分支:Linux 框架问题
probe 失败 / sysfs 没设备 ↓ 1. dmesg | grep i2c 看日志 ↓ 2. i2cdetect -l 看总线注册没 ├ 没注册 → 控制器驱动 probe 失败(设备树/clock/pinctrl) ↓ 3. i2cdetect -y N 看器件扫到没 ├ 没扫到 → → A 分支 ↓ 4. sysfs 看 client ls /sys/bus/i2c/devices/ ├ 没 client → 设备树子节点没配 / compatible 不匹配 ↓ 5. 驱动 probe 日志 ├ chip id 错 → 通信问题 / 上电时序 ├ -ENODEV → 器件验证失败 └ -EREMOTEIO → NACK(→ A/C 分支)二、常见故障速查表
| 故障现象 | 可能根因 | 排查/解决 |
|---|---|---|
| i2cdetect 扫不到 | 电源/上拉/焊接/地址错 | 万用表 + 示波器 |
| 读写偶发 NACK | 上拉弱/电容大/EMI | 测 tr/减 Rp/降速 |
| 总线 BUSY 卡死 | 从机拉低 SDA/拉伸超时 | GPIO 诊断 + 9 时钟 |
| 数据整体错位 | 时序错乱/Sr 错 | 逻辑分析仪 + CRC |
| 上升沿过缓 | Rp 大/Cb 大 | 减 Rp/分段/降速 |
| dmesg ARB_LOST | 多主冲突或 EMI 毛刺 | 单主查 EMI/滤波 |
| dmesg -121 | NACK(地址或数据) | 查器件/地址 |
| probe -ENODEV | chip ID 不符 | 上电时序/通信 |
| EEPROM 写后读挂 | 写周期拉伸 SCL | delay 5ms/配超时 |
| OLED 花屏 | 页/列地址错 | 确认寻址模式 |
| BMP280 温度 0 | 未读校准系数 | 读 0x88~0xA1 补偿 |
| MPU6050 全 0 | 未唤醒 | 写 0 到 PWR_MGMT |
| DMA 首字节错 | 命令位丢失 | 先 PIO 发读请求 |
| DMA 数据错 | cache 未 flush | flush/invalidate |
| 多任务数据错 | 无 mutex 互斥 | 加 mutex 串行化 |
三、上拉电阻速算表
3.1 Rp_min(由灌电流限制)
| VDD | I_max | Rp_min | 说明 |
|---|---|---|---|
| 3.3V | 3mA | 967Ω | (3.3-0.4)/3mA |
| 5V | 3mA | 1.53kΩ | (5-0.4)/3mA |
3.2 Rp_max(由上升时间限制)
公式:Rp_max = tr_max / (0.8473 × Cb)
| 模式 | tr_max | Cb=50pF | Cb=100pF | Cb=200pF | Cb=400pF |
|---|---|---|---|---|---|
| 标准 100k | 1000ns | 23.6k | 11.8k | 5.9k | 2.9k |
| 快速 400k | 300ns | 7.1k | 3.5k | 1.8k | 0.9k |
| 快速+ 1M | 120ns | 2.8k | 1.4k | 0.7k | — |
3.3 工程推荐值
| 场景 | 推荐 Rp | 理由 |
|---|---|---|
| 3.3V 100k,短线 | 10k | 低功耗,信号够 |
| 3.3V 400k,几器件 | 4.7k | 通用推荐 |
| 3.3V 400k,长线/多器件 | 2.2k | 补电容 |
| 5V 100k | 10k | 标准 |
| 5V 400k | 4.7k | 标准 |
| 1M 快速+ | 1k~2.2k | tr 严 |
3.4 总线电容 Cb 限制
- 标准/快速/快速+:400pF 上限
- 高速模式:100pF(有源上拉)
- 超快模式(推挽):无此限制
3.5 tr 测量与 Cb 反算
tr = 0.8473 × Rp × Cb 测 tr(示波器 0.3VDD→0.7VDD) → Cb = tr / (0.8473 × Rp) 例:tr=300ns, Rp=4.7k → Cb=75pF(正常) tr=1μs, Rp=4.7k → Cb=250pF(偏大)四、时序参数速查表
4.1 完整时序参数(NXP UM10204)
| 参数 | 标准 100k | 快速 400k | 快速+ 1M | 高速 3.4M |
|---|---|---|---|---|
| fSCL | 100k | 400k | 1M | 3.4M |
| tLOW | 4.7μs | 1.3μs | 0.5μs | 0.16μs |
| tHIGH | 4.0μs | 0.6μs | 0.26μs | 0.06μs |
| tSU_STA | 4.7μs | 0.6μs | 0.26μs | 0.16μs |
| tHD_STA | 4.0μs | 0.6μs | 0.26μs | 0.16μs |
| tSU_DAT | 250ns | 100ns | 50ns | 10ns |
| tHD_DAT | 0(0) | 0(0) | 0(0) | 0(0) |
| tSU_STO | 4.0μs | 0.6μs | 0.26μs | 0.16μs |
| tBUF | 4.7μs | 1.3μs | 0.5μs | 0.16μs |
| tr | 1000ns | 300ns | 120ns | 40ns |
| tf | 300ns | 300ns | 120ns | 40ns |
| Cb | 400pF | 400pF | 400pF | 100pF |
4.2 参数含义
| 参数 | 含义 |
|---|---|
| tLOW | SCL 低电平时间 |
| tHIGH | SCL 高电平时间 |
| tSU_STA | START 建立时间(SCL 高时 SDA 下降沿前 SCL 高多久) |
| tHD_STA | START 保持时间(START 后 SCL 低保持) |
| tSU_DAT | 数据建立时间(SCL 高前 SDA 稳定) |
| tHD_DAT | 数据保持时间(SCL 低后 SDA 保持) |
| tSU_STO | STOP 建立时间 |
| tBUF | STOP 与下个 START 间总线空闲 |
| tr | 上升时间 |
| tf | 下降时间 |
4.3 控制器分频
STM32:
CCR = F_PCLK / (2 × fSCL) (快速模式) TRISE = (1000ns / tPCLK) + 1 (100k) 或 (300ns/tPCLK)+1 (400k)DesignWare:
HCNT = (tHIGH × fPCLK) - 调整 LCNT = (tLOW × fPCLK) - 调整五、错误码与寄存器对照表
5.1 Linux 错误码
| 错误码 | 值 | 含义 |
|---|---|---|
| -ENXIO | -6 | 无此设备(地址 NACK) |
| -EREMOTEIO | -121 | I2C 远程 IO 错(NACK/ARB) |
| -ETIMEDOUT | -110 | 超时(拉伸/总线) |
| -EIO | -5 | 通用 IO 错 |
| -ENODEV | -19 | 设备不存在(probe 验证失败) |
5.2 DesignWare ABRT_SOURCE 位
| 位 | 含义 | 处理 |
|---|---|---|
| ABRT_7B_ADDR_NOACK | 7bit 地址无应答 | 器件不在,不重试 |
| ABRT_10ADDR1_NOACK | 10bit 第一字节无应答 | 地址错 |
| ABRT_10ADDR2_NOACK | 10bit 第二字节无应答 | 地址错 |
| ABRT_TXDATA_NOACK | 数据无应答 | 器件异常,STOP |
| ABRT_GCALL_NOACK | 广播无应答 | — |
| ARB_LOST | 仲裁丢失 | 退避重试 |
| ABRT_SBYTE_NORSTART | 单字节无 Sr | 软件错 |
| ABRT_HS_NORSTART | Hs 无 Sr | 软件错 |
5.3 STM32 状态位
| 位 | 寄存器 | 含义 |
|---|---|---|
| SB | SR1 | START 已发 |
| ADDR | SR1 | 地址已发(ACK) |
| TxE | SR1 | 数据寄存器空 |
| RxNE | SR1 | 数据寄存器满 |
| BTF | SR1 | 字节传输完成 |
| AF | SR1 | 应答失败(NACK) |
| ARLO | SR1 | 仲裁丢失 |
| BERR | SR1 | 总线错误 |
| BUSY | SR2 | 总线忙 |
| MSL | SR2 | 主模式 |
六、器件地址速查表
6.1 常见器件地址
| 器件 | 7bit 地址 | 说明 |
|---|---|---|
| 24Cxx EEPROM | 0x50~0x57 | 1010 + A2A1A0 |
| BMP280 | 0x76/0x77 | SDO 引脚选 |
| BMP180 | 0x77 | — |
| MPU6050 | 0x68/0x69 | AD0 引脚选 |
| HMC5883L | 0x1E | — |
| SSD1306 OLED | 0x3C/0x3D | SA0 引脚选 |
| DS1307 RTC | 0x68 | — |
| PCF8563 RTC | 0x51 | — |
| TCA9548A | 0x70~0x77 | 多路开关 |
| PCA9306 | — | 电平转换(无地址) |
| RK817 PMIC | 0x5A | 可配 |
| AXP系列 PMIC | 0x34/0x35 | — |
| SHT3x 温湿度 | 0x44/0x45 | ADDR 引脚 |
6.2 保留地址(勿用)
| 地址 | 保留用途 |
|---|---|
| 0x00 | 通用广播 |
| 0x01 | CBUS |
| 0x02~0x03 | 不同总线格式 |
| 0x04~0x07 | 高速模式主机码 |
| 0x78~0x7B | 10bit 寻址 |
| 0x7C~0x7F | 保留 |
6.3 7bit ↔ 8bit 转换
7bit: 0x50 8bit 写: 0x50 << 1 | 0 = 0xA0 8bit 读: 0x50 << 1 | 1 = 0xA1 datasheet 给 0xA0 → 实际 7bit 是 0x50 Linux reg / i2cdetect 用 7bit七、现场排查清单
7.1 新板 I2C 首次调试清单
- 器件 VDD 电压对(万用表)
- SDA/SCL 静态电平 = VDD(万用表)
- 上拉电阻焊接到位(万用表电阻档)
- SDA/SCL 未短路到地/彼此(万用表通断)
- 地址引脚(A0/A1/A2)配置正确
- 控制器 pinctrl/clock 设备树配好
- i2cdetect -l 看总线注册
- i2cdetect -y N 扫到器件
- i2cget 读 ID 寄存器验证
- 示波器看 START/地址/ACK 波形
- tr 测量达标(模式要求)
- 长时间稳定性测试(跑几小时)
7.2 故障现场排查清单
- dmesg 看错误码类型
- i2cdetect 还能扫到吗
- GPIO 读 SDA/SCL 电平
- 示波器/逻辑分析仪抓现场
- 降速测试
- 检查最近改动(硬件/软件)
- 温度/电源环境因素
- 错误统计找规律
7.3 功能安全审查清单
- 拉伸超时检测配置
- 总线 BUSY 看门狗
- 9 时钟恢复机制
- 分级恢复策略
- 重试上限
- 恢复失败进安全状态
- 故障注入测试报告
- 错误日志记录
八、I2C 系列全要点回顾
8.1 硬件基础层(01-03)
- 01 电气特性:OD 开漏 / 线与逻辑 / 上拉电阻 / 400pF 电容 / 电平 0.3~0.7VDD
- 02 上拉电容:Rp 双约束(min 灌电流/max 上升时间)/ tr=0.8473×Rp×Cb / 电平转换 BSS138/PCA9306
- 03 信号完整性:SI 看 tr 不看频率 / 临界长度 L_crit≈tr×2.9cm / 菊花链拓扑 / EMI 抑制
8.2 协议与时序层(04-07)
- 04 协议时序:START/STOP/Sr / SCL 高采样 / ACK-NACK / 7bit+RW / 随机读 Sr
- 05 多主仲裁:SCL 同步(低取最长高取最短)/ SDA 仲裁(输1读0者输)/ 时钟拉伸
- 06 速度模式:100k/400k/1M/3.4M/5M / 时序参数表 / HCNT-LCNT 分频
- 07 寻址扩展:7bit 空间 / 保留地址 / 10bit / 通用广播 / SMBus / PMBus
8.3 驱动实现层(08-11)
- 08 控制器IP:寄存器组 / 状态机 IDLE→START→ADDR→TX/RX→STOP / DesignWare/STM32 对照
- 09 传输模式:轮询(简单)/中断(通用)/DMA(大块)/ 命令位难题 / cache 一致性
- 10 错误恢复:NACK/BUSY/9时钟/拉伸超时/分级恢复/功能安全框架(I2C_unlock 专利主场)
- 11 Linux框架:i2c_adapter/algorithm/client/driver / i2c_transfer Sr / 设备树 / i2c-dev
8.4 应用实战层(12-14)
- 12 设备实战:EEPROM 页写 / BMP280 校准 / MPU6050 唤醒 / OLED 页寻址 / PMIC / RTOS 互斥
- 13 调试排查:i2c-tools / 示波器 / 逻辑分析仪 / 故障定位流程 / dmesg / ftrace
- 14 排查手册(本篇):决策树 / 速查表 / 全系列回顾
8.5 核心数据速记
| 数据 | 值 |
|---|---|
| I2C 总线电容上限 | 400pF |
| 电平阈值 | 0.3VDD(低)/ 0.7VDD(高) |
| tr 公式 | 0.8473 × Rp × Cb |
| Rp_min(3.3V) | 967Ω |
| 通用 Rp 推荐 | 4.7k(400k)/ 10k(100k) |
| 9 时钟恢复脉冲数 | 9(8 位 + ACK) |
| EEPROM 写周期 | 5ms |
| SMBus 总线超时 | 35ms |
| SMBus 拉伸上限 | 25ms |
| 标准/快速模式数 | 100k / 400k |
| 7bit 地址空间 | 128(可用 112) |
| 通用广播地址 | 0x00 |
| Hs 模式主机码 | 00001xxx |
延伸阅读
- 【I2C 技术系列 00】总目录 —— 系列总览
- [[01-I2C电气特性与物理层]] ~ [[13-I2C调试与排查]] —— 全系列
- 串口技术系列 —— UART 系列(对照)
- [[FreeRTOS_设计思想与功能模块讲解]] —— RTOS 互斥
- 【I2C 技术系列 11】I2C Linux 驱动框架 —— Linux 驱动
参考资料
- NXP UM10204(I2C 规范)
- Linux Documentation/i2c/
- Synopsys DesignWare I2C Databook
- 24C04 / BMP280 / MPU6050 / SSD1306 / RK817 Datasheet
- ISO 26262(功能安全)
【I2C 技术系列 00】总目录 · 上一篇:[[13-I2C调试与排查]] ·I2C 技术系列 · 完
✨ 感谢你的阅读 ✨
技术之路漫漫,分享是为了更好地交流。
如果本文的内容对你有启发,希望能得到你的支持:
👍 点赞|⭐ 收藏|👀 关注
如果你在调试过程中遇到了其他问题,
欢迎在评论区 💬留言,我们一起探讨。
关注我,一起交流底层开发的那些事儿!🚀