You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 01:52:11