embedded
protocol_error
ai_generated
true
I2C:SCL线时钟拉伸超时,从设备保持时钟低电平
I2C: clock stretch timeout on SCL line, slave holding clock low
ID: embedded/i2c-clock-stretch-timeout
79%修复率
86%置信度
1证据数
2024-02-10首次发现
版本兼容性
| 版本 | 状态 | 引入 | 弃用 | 备注 |
|---|---|---|---|---|
| STM32Cube_FW_L4_V1.18.0 | active | — | — | — |
| IAR EWARM 9.40.1 | active | — | — | — |
| ARM GCC 10.3.1 | active | — | — | — |
| FreeRTOSv202212.01 | active | — | — | — |
根因分析
I2C从设备拉伸时钟(保持SCL低电平)超过主设备超时周期,通常由内部处理缓慢或总线锁定引起。
English
I2C slave device stretches the clock (holds SCL low) beyond the master's timeout period, often due to slow internal processing or bus lock.
官方文档
https://www.st.com/resource/en/application_note/dm00108059-i2c-timing-configuration-on-stm32-mcus-stmicroelectronics.pdf解决方案
-
Increase I2C timeout in HAL_I2C_Master_Transmit(): set hi2c1.Init.Timing = 0x20C0E0FF; (for 100 kHz) and use HAL_I2C_Master_Transmit() with a timeout of 10000 ms instead of default 1000 ms.
-
Implement software reset of I2C peripheral after timeout: call HAL_I2C_DeInit(&hi2c1); HAL_I2C_Init(&hi2c1); then retry the transaction up to 3 times.
-
Use I2C recovery sequence: toggle SCL 9 times while SDA is high to release the slave: for(int i=0;i<9;i++) { HAL_GPIO_WritePin(SCL_GPIO_Port, SCL_Pin, GPIO_PIN_RESET); delay_us(5); HAL_GPIO_WritePin(SCL_GPIO_Port, SCL_Pin, GPIO_PIN_SET); delay_us(5); }
无效尝试
常见但无效的做法:
-
Reducing I2C bus speed from 400 kHz to 100 kHz
80% 失败
Slower speed may increase stretch duration, making timeout more likely.
-
Disabling clock stretching in the slave device configuration
90% 失败
Many I2C slaves require clock stretching for proper operation; disabling it may cause data corruption.
-
Adding a hardware pull-up resistor on SCL line
85% 失败
Pull-up resistors are already present; this does not address the slave holding the line low.