告别delay()!用Arduino Uno定时器中断实现精准多任务(附TimerOne库实战)
当你第一次用Arduino点亮LED时,delay(1000)可能是最亲切的函数——简单粗暴地让灯亮一秒、灭一秒。但当你尝试同时读取传感器数据、控制电机转速并响应按键输入时,这个"老朋友"立刻变成噩梦:按下按钮没反应、传感器数据丢失、电机动作卡顿... 这些正是阻塞式编程的典型症状。其实Arduino Uno内置的硬件定时器可以完美解决这些问题,而TimerOne库让定时器中断变得像点外卖一样简单。
1. 为什么你的Arduino项目需要定时器中断
在面包板上堆满传感器的创客们迟早会遇到这样的场景:需要以精确的50ms间隔采集环境温度,同时每200ms检查一次按键状态,还要让LED保持呼吸灯效果。用delay()尝试实现时,你会发现:
- 时序失控:delay(50)之后插入其他操作会导致实际采样间隔漂移
- 响应迟钝:长延时期间无法检测紧急停止信号
- 资源浪费:CPU在delay期间完全空转
硬件定时器中断的工作原理就像厨房里的多功能计时器:设置好时间后,你可以专心切菜(主循环处理其他任务),计时器到点会自动鸣响(触发中断函数)。Arduino Uno的ATmega328P芯片内置三个硬件定时器:
| 定时器 | 位数 | 默认用途 | 可用性 |
|---|---|---|---|
| Timer0 | 8位 | delay(), millis() | 高风险修改 |
| Timer1 | 16位 | Servo库 | 最佳候选 |
| Timer2 | 8位 | Tone()函数 | 次优选择 |
提示:修改Timer0会直接影响millis()和delay()的准确性,新手建议优先选用Timer1
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. TimerOne库快速入门
这个不足10KB的库将复杂的寄存器配置封装成三个直观的方法:
cpp复制#include <TimerOne.h>
void setup() {
// 初始化定时器,设置中断周期为500ms(单位微秒)
