如何在RPI_PICO_TimerInterrupt中重置定时器以获取已知起始时间?
解决方案:用GPS PPS同步RPI_PICO_Timer定时器相位
核心思路
要实现PPS上升沿触发后,定时器从0开始精准计时并按固定周期触发中断,不能依赖库中现有的restartTimer()(会引入启停延迟),而是直接操作树莓派Pico的硬件定时器寄存器,在PPS中断内重置定时器计数器,强制对齐计时起点。
实现步骤
1. 确认库的底层访问方法
RPI_PICO_TimerInterrupt库提供了getTimer()方法,可获取底层的hw_timer_t指针,通过这个指针直接操作Pico的硬件定时器寄存器。
2. 编写PPS中断服务程序
在PPS上升沿触发的中断里,重置定时器计数器为0,让计时从当前时刻(PPS上升沿)开始:
// 定义PPS引脚,根据实际接线修改 #define PPS_PIN 2 // 全局定时器对象 RPI_PICO_Timer elementTimer(1); // 定时器周期,比如1ms(每秒触发1000次中断),根据需求修改 #define TIMER_RATE 1000 void PPS_ISR() { // 直接重置定时器计数器为0,对齐PPS上升沿 hw_timer_set_count(elementTimer.getTimer(), 0); }
3. 初始化配置
在setup()中完成PPI引脚中断、定时器的初始化:
void setup() { Serial.begin(115200); // 配置PPS引脚为上拉输入,上升沿触发中断 pinMode(PPS_PIN, INPUT_PULLUP); attachInterrupt(digitalPinToInterrupt(PPS_PIN), PPS_ISR, RISING); // 初始化定时器并绑定中断服务程序 if (!elementTimer.attachInterruptInterval(TIMER_RATE, TimerISR)) { Serial.println("定时器初始化失败"); while(1); } } // 定时器中断服务程序,按TIMER_RATE周期触发 void TimerISR() { // 这里写你的业务逻辑,比如输出脉冲、计数等 } void loop() { // 主循环逻辑 }
关键说明
- 为什么不用
restartTimer()?该方法会先停止定时器再重启,启停过程会引入微秒级延迟,无法精准对齐PPS上升沿。 - 直接操作寄存器的优势:
hw_timer_set_count()是Pico SDK的底层硬件操作,执行速度极快,不会在中断内引入额外延迟,保证计时精度。 - 定时器周期计算:如果需要每秒触发N次中断,设置
TIMER_RATE = 1000000 / N(单位:微秒),比如N=100则TIMER_RATE=10000。
内容的提问来源于stack exchange,提问作者David Kazdan
相关产品推荐
相关产品推荐

