NXP JN5169 使用看门狗定时器
一、看门狗定时器介绍
JN5169 提供了看门狗定时器以防止软件锁定。它通过计算高速 RC 系统时钟(该振荡器运行在 27MHz 或 32MHz 频率下)的周期进行操作。提供了一个预分频器,以允许将到期时间设置在典型的 8 ms 到 16.4 s 之间(取决于高速 RC 精度:+30%,-15%)。在预配置的定时器周期内未能重启看门狗定时器将导致芯片复位。如果触发了看门狗,则会置位一个状态位,以便软件可以将看门狗启动的复位与其他复位区分开,并且一旦重启就可以执行任何所需的恢复。看门狗可以选择导致异常而不是复位,这是可选的。这样可以保留内存的状态,对于调试很有用。
上电,复位,从深度睡眠开始或从睡眠开始后,看门狗始终以最大的超时时间启用,并将开始计数,就好像它刚刚重新启动一样。在软件控制下,可以禁用看门狗。如果启用了该功能,则用户必须定期重新启动看门狗定时器,以使其停止工作并导致复位。看门狗即使在休眠模式时也连续运行。但是,看门狗在睡眠或深度睡眠期间,或者在硬件调试器控制了 CPU 时无法运行。如果启用,它将在调试器调试 CPU 后自动重启。
注:
- 在上电、复位或从睡眠模式下唤醒后,看门狗定时器使能,可能的最大超时周期为 16392ms(不管在任何睡眠或复位之前它的状态如何)。
- 可配置看门狗定时器调用一个超时异常。这允许调试在应用开发期间导致超时的情况。
从上面的图可以看出,看门狗定时器的时钟源是内部 RC 振荡器,那么由于振荡器的偏差,得到的实际超时周期可能比计算的值少 18%。
二、示例代码
#define TIMEOUT_PERIOD (500) //看门狗定时器超时周期(单位ms),实际超时周期需要看计算出来的系数
PUBLIC void AppColdStart (void)
{
uint8 u8Prescale; //超时周期系数
uint16 wt_value; //看门狗超时周期进度(0-255)
/*等待系统时钟切换为外部32MHz晶振*/
while (bAHI_GetClkSource() == TRUE);
vAHI_WatchdogStop();//上电、复位或从睡眠模式下唤醒后,默认看门狗定时器以最大的超时时间使能
(void)u32AHI_Init();
vUartInit();
vAHI_DelayXms(2000);
vPrintf("System init...\n");
if(bAHI_TrimHighSpeedRCOsc()){
vPrintf("校准内部 RC 振荡器至 32 MHz\n");
}
else{
vPrintf("内部 RC 振荡器校准失败\n");
}
/**
* 根据下列公式,函数使用 prescale 的值来计算超时周期(以毫秒为单位):
* 超时周期 = 8ms 如果 Prescale=0
* 超时周期 = [2 ^ (Prescale - 1) + 1] × 8ms 如果 1 ≤ Prescale ≤ 12
* 这得出超时周期的范围为 8ms 到 16392ms。
*/
u8Prescale = log(TIMEOUT_PERIOD / 8 - 1) / log(2) + 1 + 0.5;//+0.5是为了取整
//由 500ms 计算得 u8Prescale = 7,u8Prescale = 7 时看门狗定时器为520ms(忽略高速 RC 精度:+30%,-15%误差)
//看门狗定时器的时钟源是内部 RC 振荡器,得到的实际超时周期可能比计算的值少 18%(实际误差看运行效果)
//520 * (1 - 18%) ≈ 426 ms(实际误差看运行效果)
vPrintf("u8Prescale = %d\n", u8Prescale);
vAHI_WatchdogRestart();
vAHI_WatchdogStart(u8Prescale);
while (1) {
wt_value = u16AHI_WatchdogReadValue();
if(wt_value == 255){ //看门狗定时器准备到达超时周期
vAHI_WatchdogRestart(); //喂狗
vPrintf("WatchdogRestart\n");
}
}
}
PUBLIC void AppWarmStart (void)
{
AppColdStart();
}
看串口打印时间,实际超时周期约为 500ms(系数为 7 时超时周期为 520 ms),与计算值 520 ms 误差为 (520 - 500)÷ 520 ≈ 3.8%
效果图: