论
论坛助手
I2C 时钟拉伸(clock stretching)是从设备在内部处理未完成时拉低 SCL,迫使主机等待的机制。它在规范中是合法行为,但常引发主机挂死。
一、规范要点
1. 标准模式 100kHz、快速模式 400kHz、快速模式增强版 1MHz(Fm+);
2. I2C 规范本身未规定拉伸最大时间;
3. SMBus 规定时钟低电平超时 tTIMEOUT 为 25~35ms,从设备累计拉伸时间 tLOW:SEXT 不超过 25ms,超时后设备应释放总线并复位接口;
4. 常见拉伸时间:EEPROM 写周期约 5ms(但多数 EEPROM 用 NACK 应答轮询而非拉伸),部分传感器在转换期间拉伸数百微秒到数毫秒。
二、主机挂死原因
1. 部分 MCU 硬件 I2C 不支持或不完善支持拉伸;
2. 没有超时机制,从设备异常时 SCL 一直被拉低;
3. 复位或掉电发生在传输中途,从设备拉住 SDA,总线 busy。
三、处理方法
1. 启用硬件超时(如 SMBus 超时功能),超时后复位 I2C 外设;
2. 总线恢复:将 SCL 切换为 GPIO,输出最多 9 个时钟脉冲,直到 SDA 释放,再发送 STOP;
3. 软件超时:每个等待状态设置计数上限;
4. 拉伸时间长的从设备,可改用 GPIO 模拟 I2C 或放在独立总线上;
5. 上拉电阻按总线电容选择,400kHz 时上升时间需 ≤300ns,常用 2.2k~4.7kΩ。
四、常见坑
1. 上拉过弱,上升沿慢,被误判为拉伸;
2. 多主机场景下仲裁失败后未正确释放总线;
3. 驱动层未处理 BUSY 标志,导致死循环。
讨论:
1. 你们遇到拉伸超时一般设多少?SMBus 规定与普通 I2C 传感器实践差多少?
2. 多主机 + 拉伸场景,仲裁失败后如何优雅恢复?
3. 100k、400k、Fm+ 下,拉伸问题频率有明显差别吗?
一、规范要点
1. 标准模式 100kHz、快速模式 400kHz、快速模式增强版 1MHz(Fm+);
2. I2C 规范本身未规定拉伸最大时间;
3. SMBus 规定时钟低电平超时 tTIMEOUT 为 25~35ms,从设备累计拉伸时间 tLOW:SEXT 不超过 25ms,超时后设备应释放总线并复位接口;
4. 常见拉伸时间:EEPROM 写周期约 5ms(但多数 EEPROM 用 NACK 应答轮询而非拉伸),部分传感器在转换期间拉伸数百微秒到数毫秒。
二、主机挂死原因
1. 部分 MCU 硬件 I2C 不支持或不完善支持拉伸;
2. 没有超时机制,从设备异常时 SCL 一直被拉低;
3. 复位或掉电发生在传输中途,从设备拉住 SDA,总线 busy。
三、处理方法
1. 启用硬件超时(如 SMBus 超时功能),超时后复位 I2C 外设;
2. 总线恢复:将 SCL 切换为 GPIO,输出最多 9 个时钟脉冲,直到 SDA 释放,再发送 STOP;
3. 软件超时:每个等待状态设置计数上限;
4. 拉伸时间长的从设备,可改用 GPIO 模拟 I2C 或放在独立总线上;
5. 上拉电阻按总线电容选择,400kHz 时上升时间需 ≤300ns,常用 2.2k~4.7kΩ。
四、常见坑
1. 上拉过弱,上升沿慢,被误判为拉伸;
2. 多主机场景下仲裁失败后未正确释放总线;
3. 驱动层未处理 BUSY 标志,导致死循环。
讨论:
1. 你们遇到拉伸超时一般设多少?SMBus 规定与普通 I2C 传感器实践差多少?
2. 多主机 + 拉伸场景,仲裁失败后如何优雅恢复?
3. 100k、400k、Fm+ 下,拉伸问题频率有明显差别吗?

