如何为Arduino Nano 33 BLE Sense配置看门狗及其中断模式
Arduino Nano 33 BLE Sense(nRF52840)看门狗中断模式实现方案
Arduino Nano 33 BLE Sense搭载的nRF52840芯片使用RTC看门狗,与AVR系列看门狗架构完全不同,无法直接沿用<avr/wdt.h>的写法。以下是实现类似AVR看门狗中断异步任务的两种方案:
方案1:基于Arduino官方nRF52核心API(快速实现)
官方nRF52核心封装了基础看门狗功能,可通过回调函数替代AVR的ISR()实现异步任务:
#include <Arduino.h> #include <nrf.h> volatile bool wdtTriggered = false; byte ledState = LOW; int loopCount = 0; // 看门狗超时回调函数 void wdtCallback() { Serial.println("异步任务在看门狗回调中执行"); digitalWrite(LED_BUILTIN, ledState); ledState = !ledState; wdtTriggered = true; } void setup() { pinMode(LED_BUILTIN, OUTPUT); Serial.begin(9600); while(!Serial); Serial.println("== 系统重启 =="); // 初始化看门狗,设置超时时间500ms(与AVR示例配置一致) if (!Watchdog.enable(500)) { Serial.println("看门狗初始化失败"); while(1); } // 注册超时回调 Watchdog.onTimeout(wdtCallback); } void loop() { Serial.print("循环次数 #"); Serial.println(loopCount); if (loopCount++ % 2) { Serial.println("执行偶数分支任务"); delay(1200); } else { Serial.println("执行奇数分支任务"); delay(4800); } // 喂狗:必须在超时前调用,避免触发系统重启 if (wdtTriggered) { Watchdog.reset(); wdtTriggered = false; } }
方案2:直接操作nRF52840寄存器(精细控制)
如果需要底层寄存器级的自定义配置,可直接操作nRF52840的看门狗硬件:
#include <Arduino.h> volatile byte ledState = LOW; int loopCount = 0; // 看门狗中断服务函数 void WDT_IRQHandler(void) { // 清除中断标志位 NRF_WDT->EVENTS_TIMEOUT = 0; Serial.println("异步任务在看门狗ISR中执行"); digitalWrite(LED_BUILTIN, ledState); ledState = !ledState; // 喂狗:重置看门狗计数器 NRF_WDT->RR[0] = WDT_RR_RR_Reload; } void setup() { pinMode(LED_BUILTIN, OUTPUT); Serial.begin(9600); while(!Serial); Serial.println("== 系统重启 =="); // 配置看门狗:睡眠时运行、调试暂停时停止、禁用窗口模式 NRF_WDT->CONFIG = WDT_CONFIG_SLEEP_Run << WDT_CONFIG_SLEEP_Pos | WDT_CONFIG_HALT_Pause << WDT_CONFIG_HALT_Pos; // 设置超时时间500ms:基于32kHz RTC时钟,计算得16384 ticks NRF_WDT->CRV = 16384; // 启用喂狗通道0 NRF_WDT->RREN = WDT_RREN_RR0_Enabled << WDT_RREN_RR0_Pos; // 启用看门狗中断 NRF_WDT->INTENSET = WDT_INTENSET_TIMEOUT_Set << WDT_INTENSET_TIMEOUT_Pos; // 配置中断优先级并启用 NVIC_SetPriority(WDT_IRQn, 3); NVIC_EnableIRQ(WDT_IRQn); // 启动看门狗 NRF_WDT->TASKS_START = 1; } void loop() { Serial.print("循环次数 #"); Serial.println(loopCount); if (loopCount++ % 2) { Serial.println("执行偶数分支任务"); delay(1200); } else { Serial.println("执行奇数分支任务"); delay(4800); } // 喂狗:必须在超时周期内完成 NRF_WDT->RR[0] = WDT_RR_RR_Reload; }
关键注意事项:
- nRF52840看门狗基于32kHz RTC时钟,超时时间计算公式:
超时时间(秒) = CRV寄存器值 / 32768 - 若需启用自动重启功能,修改
CONFIG寄存器即可:NRF_WDT->CONFIG |= WDT_CONFIG_Enable_Enabled; - 喂狗操作必须在超时周期内执行,否则会触发中断或系统重启(取决于配置)
内容的提问来源于stack exchange,提问作者tjbtjbtjb
相关产品推荐
相关产品推荐

