ESP32硬件定时器首次正常触发后后续回调未执行的问题求助
解决ESP32硬件定时器第二次触发后回调不执行的问题
你的问题出在定时器的闹钟状态管理上:第一次触发后,闹钟要么被自动禁用(单次模式),要么被timerStop()停止计数但状态未正确处理,导致第二次调用timerRestart()时,定时器计数重启但闹钟未启用,无法触发回调。
修改后的代码及说明
1. 回调函数调整
void IRAM_ATTR LaunchTimerEnd() { function_to_turn_off_GPIO(); portENTER_CRITICAL_ISR(&timerMux); input_values.LTE_value = true; // 通知FSM定时器已完成 portEXIT_CRITICAL_ISR(&timerMux); timerAlarmDisable(launch_current_timer); // 显式禁用闹钟,确保状态正确 Serial.println("***LT OFF"); }
- 移除
timerStop(),改用timerAlarmDisable():我们需要禁用闹钟触发而非单纯停止计数,避免后续启动时状态混乱。
2. 定时器初始化调整
void timerSetup() { launch_current_timer = timerBegin(0, 80, true); timerAttachInterrupt(launch_current_timer, &LaunchTimerEnd, false); timerAlarmWrite(launch_current_timer, 5000000, false); // 设置为单次触发(5秒) // 初始状态不启用闹钟,避免定时器自动运行 input_values.LTE_value = true; }
- 将
timerAlarmWrite()的最后参数设为false(单次触发),匹配你“每次启动后只运行一次”的需求。 - 去掉初始的
timerAlarmEnable(),让定时器默认处于未激活状态。
3. 定时器启动函数调整
void LaunchTimerStart() { portENTER_CRITICAL(&timerMux); input_values.LTE_value = false; // 通知FSM定时器正在运行 portEXIT_CRITICAL(&timerMux); Serial.println("***LT ON"); timerRestart(launch_current_timer); // 重置定时器计数到0 timerAlarmEnable(launch_current_timer); // 启用闹钟,触发5秒后的中断 }
- 每次启动时先重置计数到0,再启用闹钟:确保定时器从0开始计时,且闹钟处于激活状态,到时间必然触发回调。
额外注意事项
- 如果定时器0被其他代码占用,可尝试更换定时器编号(ESP32支持0-3共4个硬件定时器)。
IRAM_ATTR必须保留,中断回调函数需存储在IRAM中以保证执行效率。- 中断内的
Serial.println()仅用于调试,正式代码建议移除或改用非阻塞日志方式。
内容的提问来源于stack exchange,提问作者user1045680
相关产品推荐
相关产品推荐

