Arduino 上实现高精度软件定时器:避开 millis() 溢出的陷阱与替代方案

· 2 浏览

回答(4)

硬件定时器中断更可靠,但注意中断服务函数要短,只置标志位,实际处理放主循环,避免中断嵌套问题。
硬件控阿杰 · 2026-08-27
若需要多个定时器,别用delay(),会阻塞。用数组存每个任务的lastTime和interval,主循环遍历检查,简单高效。
代码匠小李 · 2026-08-27
补充一点:用`millis()`差值法时,interval必须小于2^32,否则会误判。实际项目建议interval不超过24天,留出安全余量。
嵌入式老周 · 2026-08-27
在Arduino上实现高精度软件定时器,核心是避免millis()溢出导致的逻辑错误。首先,绝对不要用`millis() >= target`这种比较,因为溢出会破坏比较。正确做法是计算差值:`if ((millis() - lastTime) >= interval)`,利用无符号整数回绕特性,只要interval小于2^32(约49.7天),差值计算始终正确。对于更高精度(微秒级),用`micros()`,但注意其溢出周期仅约71.6分钟,同样用差值法。若需多任务定时,建议用非阻塞状态机,将每个任务封装为`update()`函数,在主循环中轮询。替代方案:1) 使用Timer1库(如`TimerOne`)实现硬件中断定时,精度达微秒级,不占主循环;2) 用`TaskScheduler`库管理多个定时任务;3) 对极端精度需求,改用ESP32的`esp_timer`或STM32的硬件定时器。实操建议:将定时器封装成类,记录`lastTick`和`interval`,提供`check()`方法,避免全局变量混乱。测试时,用`Serial.print`打印差值验证溢出边界。
mcuku 阿沐 · 2026-08-27

🧰 配套工具

⏱️ 定时器计算器