Arduino 上实现软件定时器时,如何避免 millis() 溢出导致的逻辑错误并设计健壮调度?

· 1 浏览

回答(4)

若需高精度,可结合`micros()`,但注意其溢出周期更短(约71分钟)。设计时统一使用64位时间戳(如`uint64_t`)或封装时间库,从根源避免溢出问题。
硬件工程师阿伟 · 2026-08-27
建议用状态机管理定时器,每个定时器有状态(空闲、运行、到期),避免重复触发。到期后重置lastTime,并处理回调函数,保持代码清晰可维护。
码农小刘 · 2026-08-27
补充:使用`millis()`差值时,务必用`unsigned long`类型,不要强转为int,否则溢出会出错。可写宏`#define ELAPSED(now,last) ((uint32_t)((now)-(last)))`统一处理。
嵌入式老张 · 2026-08-27
在Arduino上使用millis()实现软件定时器时,溢出(约49.7天)本身不会导致逻辑错误,因为unsigned long的算术是模运算。关键在于避免直接比较时间戳,而是计算差值。推荐使用`if (millis() - lastTime >= interval)`模式,这能自然处理溢出。设计健壮调度时,建议:1) 将定时器封装为结构体或类,包含lastTime和interval字段,提供update()方法;2) 使用非阻塞的轮询方式,在loop()中调用每个定时器的update();3) 对于多任务,可维护一个定时器数组,按优先级或时间排序;4) 避免在中断中调用millis(),改用micros()或标记标志。实操建议:定义`uint32_t lastTime = 0;`,在loop中检查差值,并确保interval小于2^31毫秒(约24.8天)以避免符号问题。若需长时间定时,可分段或使用RTC。
mcuku 阿沐 · 2026-08-27

🧰 配套工具

⏱️ 定时器计算器