3. I2C通信故障排查
I2C在Camera模组里,就像人的神经系统。主控通过它给sensor发指令,sensor把状态回传。一旦这条线出问题,模组要么不工作,要么出图异常。我调试过的Camera项目里,I2C故障占了差不多三成。今天咱们就把I2C从协议到排查,彻底捋一遍。
核心思路: I2C故障排查 = 理解协议 + 算对电阻 + 看波形 + 查地址。缺一不可。
3.1 I2C总线协议速览
I2C是两根线的串行总线:SCL(时钟)和SDA(数据)。所有设备挂在上面,主控是“老板”,sensor是“员工”。老板发号施令,员工回应。
基本通信流程是这样的:
- 起始条件: SCL高电平时,SDA从高拉低。表示“我要开始通信了”。
- 发送设备地址: 主控发出7位或10位地址,加上读写位(0=写,1=读)。
- 等待ACK: 每个字节发完后,从设备必须拉低SDA回应ACK。如果没拉低,就是NACK。
- 数据传输: 主控发寄存器地址,再发数据。每字节后都有ACK/NACK。
- 停止条件: SCL高电平时,SDA从低拉高。表示“通信结束”。
这里有个关键点:SCL时钟由主控产生,sensor只能拉低SCL做时钟拉伸(clock stretching),但大部分Camera sensor不用这个功能。
我的经验: 调试时先确认起始和停止条件是否完整。我遇到过不少次,主控发了起始条件后没发停止,总线就一直被占用着。
3.2 上拉电阻计算——算不对就等着出问题
I2C总线是开漏输出,必须加上拉电阻才能拉高电平。电阻选大了,上升沿太慢;选小了,灌电流太大。我见过有人随便焊个4.7kΩ上去,结果400kHz下波形惨不忍睹。
上拉电阻有两个边界:
| 参数 | 公式 | 说明 |
|---|---|---|
| 最小值(Rmin) | Rmin = (VDD - VOL) / IOL | VOL是低电平电压(通常0.4V),IOL是灌电流(通常3mA~20mA) |
| 最大值(Rmax) | Rmax = tr / (0.8473 × Cb) | tr是上升时间(100kHz时1μs,400kHz时300ns),Cb是总线电容 |
举个例子:VDD=3.3V,总线电容Cb=50pF,400kHz下:
- Rmin = (3.3 - 0.4) / 0.003 = 967Ω(取3mA灌电流)
- Rmax = 300ns / (0.8473 × 50pF) ≈ 7.08kΩ
所以电阻范围是1kΩ ~ 7kΩ。我一般取中间值2.2kΩ或3.3kΩ,兼顾速度和功耗。
注意: 如果总线上挂多个设备,总线电容会累加。我曾经在一个项目里挂了4个sensor,总线电容超过200pF,2.2kΩ的电阻上升沿都超了。后来换成1.5kΩ才搞定。
3.3 波形抓取与ACK/NACK分析
示波器是排查I2C故障的“照妖镜”。我习惯用单次触发模式抓取起始条件,然后看整个通信过程。
抓波形时重点关注这几个点:
- SCL和SDA的幅值: 低电平必须低于0.3×VDD,高电平必须高于0.7×VDD。
- 上升沿和下降沿: 400kHz下上升沿应小于300ns,下降沿应小于100ns。
- ACK/NACK位置: 第9个SCL时钟周期,SDA被拉低就是ACK,保持高就是NACK。
常见的波形问题:
- SDA一直低: 某个设备把总线拉死了。断开所有从设备,一个一个接回去排查。
- SCL有毛刺: 可能是走线太长或阻抗不匹配。加个小电容(10pF~50pF)对地滤波。
- ACK变成NACK: 地址不对、设备没上电、或者设备忙。先确认地址,再量供电。
避坑指南: 我曾经遇到一个sensor,每次读寄存器都返回NACK。抓波形发现地址发对了,但sensor在第9个时钟前没准备好。后来在地址字节后加了100μs延时,问题就解决了。说白了,有些sensor启动慢,需要等一等。
3.4 设备地址冲突——两个设备抢一条线
I2C总线上每个设备必须有唯一的地址。Camera sensor的地址通常是7位,比如0x30或0x6C。如果两个sensor用了同一个地址,主控发指令时两个都会响应,数据就乱套了。
地址冲突的典型表现:
- 读寄存器时,有时返回正确值,有时返回0xFF或乱码。
- 写寄存器时,一个sensor写进去了,另一个没写进去。
- 波形上看,SDA在ACK位置有“竞争”——一个设备拉低,另一个没拉低,导致电平不确定。
排查方法:
- 查datasheet: 确认每个sensor的默认地址和可配置地址。
- 量ADDR引脚: 很多sensor通过ADDR引脚的电平来改变地址。高电平一个地址,低电平另一个。
- 逐个上电: 只给一个sensor供电,看通信是否正常。再给另一个供电,看地址是否冲突。
注意: 有些sensor的地址是7位,但I2C协议里发的是8位(左移1位+读写位)。比如地址0x30,实际发的是0x60(写)或0x61(读)。调试时别搞混了。
3.5 知识结构总览
下面这张图把I2C故障排查的整个思路串起来了。从协议理解到波形分析,再到地址排查,每一步都有对应的工具和方法。
3.6 实战排查步骤
遇到I2C问题,我一般按这个顺序来:
- 量电压: 确认VDD和VIO是否正常。sensor没供电,I2C肯定不通。
- 看上拉: 用万用表量SCL和SDA对地电阻,确认上拉电阻在合理范围。
- 抓波形: 示波器看起始条件、地址、ACK。确认主控发了,sensor回了。
- 查地址: 确认sensor地址和代码里写的一致。注意7位和8位的区别。
- 试读写: 先写一个已知寄存器,再读回来。看数据是否一致。
总结: I2C故障排查,说白了就是“协议对不对、电阻对不对、波形对不对、地址对不对”。把这四点吃透了,Camera模组的I2C问题基本都能搞定。