I2C 调试经验分享

ESP_houwenxiang
Posts: 118
Joined: Tue Jun 26, 2018 3:09 am

I2C 调试经验分享

Postby ESP_houwenxiang » Fri Nov 16, 2018 5:52 am

最近在调试 ESP32 上 I2C 的问题,发现一个容易被忽略的细节,这里和大家分享一下 ;)

直接进入主题,首先说一下背景:

我们使用 ESP32 上的 I2C 和一片 LED 控制芯片进行通讯,SCL 频率为 10K。ESP32 I2C 作为 master,在控制 LED 渐变时(会频繁的向设备写 12 字节的数据),会导致灯全部熄灭,芯片不能正常工作,除非重新初始化。

使用示波器抓取的 I2C 总线上异常的波形,如图1所示:
pic1.png
图1 异常通讯波形
pic1.png (1.17 MiB) Viewed 5282 times
从波形可以看到,master 在写完 12 字节的数据后并没有发送停止位,而是继续发送 SCL 时钟向 LED 控制芯片一直写入数据直到软件超时复位 master。这就导致 LED 控制芯片的初始化参数被修改而无法工作。master 需要写的数据已经全部发送完成,如果没有发送停止位就会导致状态机出错。但为什么 ESP32 的 I2C 会丢失 stop 信号呢 :?: 我们曾经对 ESP32 I2C 进行过大量测试,并没有出现 master 丢失 stop 信号的情况。所以怀疑是 I2C 总线受到了干扰。之后对硬件上的 I2C 总线和电源进行了测量,但从示波器抓取的波形上看,并未发现比较严重的干扰,但故障依然很容易复现(master 丢失 stop)。我们使用逻辑分析仪抓取通讯波形,采样频率设置为 100M,发现软件解析出的时序出现了问题。将分析仪抓取的波形放大后发现,很多 SCL 的上升沿出现了大约 20ns 的一个干扰。如图2所示:
pic2.png
图2 逻辑分析抓取的通讯波形
pic2.png (139.27 KiB) Viewed 5282 times
我们怀疑就是这些高频的噪声影响了ESP32 I2C master 的时序。因为 I2C master 在向外输出信号时,也会回采输出的信号,这些干扰很容易导致 master 出现故障。但从示波器抓取的波形来看,SCL 的上升沿没有发现 20ns 的干扰。不过 I2C 总线上接了较大的滤波电容,导致 SCL 的上升沿很缓慢。我们判断很有可能是 SCL 信号电平在中间电平上下抖动。 ESP32 I2C 以 80M 的频率采样 SCL 总线电平时就很有可能采到了这种都抖动。我们尝试将逻辑分析仪的采样频率设置为 400K, 发现采集到的数据正常。如图3 所示:
suc2.png
图3 400K 采样时抓取的波形
suc2.png (66.14 KiB) Viewed 5282 times
所以基本可以肯定是 SCL 上升沿太缓慢导致 ESP32 采集到了干扰信号。我们提供的解决办法是滤除这些高频的脉冲序列。ESP32 采样周期是 12.5ns, 而线上的这些干扰基本都是 20ns, 所以我们只要将这些 20ns 的脉冲信号滤除就可以了。ESP32 I2C 支持硬件滤波功能,当采样到的脉冲周期小于配置的阈值时,这些脉冲会被忽略。I2C_SCL_FILTER_CFG_REG 和 I2C_SDA_FILTER_CFG_REG 用于使能硬件滤波功能和配置滤除的信号周期。我们向这两个寄存器写入 0xf 后,经过长时间测试, ESP32 I2C 与 LED 控制芯片的通讯很稳定。

在使用 ESP32 上 I2C 时,需要注意以下两点:
1. 当总线上有 高频干扰时最好使能硬件滤波。
2. 在 I2C 总线上不要接太大的滤波电容,如果 SCL 上升沿非常缓慢,在中间电平附近持续时间过长,则硬件滤波也是无法滤除这种信号的。
wookooho

Who is online

Users browsing this forum: No registered users and 41 guests