ESP32定时器中断与loop()函数同步问题解决
ESP32定时器中断与loop()函数同步问题解决
在使用ESP32的硬件定时器时,可能会遇到定时器中断没有按预期执行的情况。例如,以下代码的目标是使用定时器中断每隔700微秒累加一次变量pulseState的值,并在loop()函数中打印。cpp#include <Arduino.h>#include <esp32-hal-timer.h>
volatile int pulseState = 0;hw_timer_t* timer = NULL;
void IRAM_ATTR onTimer() { pulseState += 3;}
void setup() { Serial.begin(115200); timer = timerBegin(0, 80, true); // 使用硬件定时器0,预分频因子为80,使定时器频率为1 MHz timerAttachInterrupt(timer, &onTimer, true); // 将定时器中断处理函数附加到定时器上 timerAlarmWrite(timer, 700, true); // 设置定时器的定时间隔,并设置为自动重复 timerAlarmEnable(timer); // 启用定时器}
void loop() { Serial.println(pulseState); delay(700);}
然而,实际运行时发现pulseState只在程序开始时被累加了一次,之后就停止了。这是因为loop()函数中的delay(700)语句使用了毫秒作为单位,而定时器timerAlarmWrite(timer, 700, true)则使用了微秒作为单位。这意味着loop()函数每隔700毫秒才执行一次,而定时器中断每隔700微秒触发一次,导致大部分的中断都被错过。
解决方法
要解决这个问题,需要将loop()函数中的延迟时间单位也改为微秒,可以使用delayMicroseconds()函数:cppvoid loop() { Serial.println(pulseState); delayMicroseconds(700);}
修改后,loop()函数每隔700微秒就会执行一次,与定时器中断的频率一致,从而确保每次中断都能被及时处理。
总结
在编写ESP32定时器中断程序时,务必注意时间单位的一致性,避免因为时间单位不匹配导致中断丢失或程序逻辑错误。
原文地址: https://www.cveoy.top/t/topic/zcQ 著作权归作者所有。请勿转载和采集!