看过国民技术几个系列的通用 MCU ,我发现这些 MCU 都会配备独立看门狗定时器(IWDG)和窗口看门狗定时器(WWDG)。那么什么是看门狗定时器?如何使用国民技术的看门狗定时器呢?感兴趣的朋友们往下看。
什么是看门狗定时器?
看门狗定时器(WDG, Watch Dog Timer)实际上就是一个计数器。它的名字很好诠释了它在 MCU 应用中的功能。打开看门狗定时器功能,隔一段时间就喂这只狗一个数值,这只狗就开始倒数,如果到了规定时间,还没有喂狗的话,这只狗就要“叫”了。它会产生中断提醒主人(MCU) :时间到了,主人怎么还不搭理我?或者干脆就把主人复位了。
有了这只宠物,我们可以做什么呢?看门狗虽然很会吃,但也会看家护院。如果 MCU 程序运行到一个地方就死机了,看门狗可以通过复位唤醒 MCU,或者产生中断,让 MCU 做处理。另外,MCU 休眠的时候,也可以通过看门狗唤醒。所以,看门狗定时器可以提高系统的稳定性,在单片机程序的调试和运行中都有着重要的意义。
现在我们来了解一下国民技术 MCU 的看门狗,看看看门狗是如何使用的吧?
1、独立看门狗(IWDG)
独立看门狗(IWDG)由专用时钟源(LSI)驱动,其工作状态不受主时钟故障影响。因此,IWDG 适用于独立工作在主程序之外且对时间精度要求较低的场合。IWDG 主要性能如下:
- 独立运行的12 位递减计数器。
- RC 振荡器提供独立时钟源,待机和深度睡眠模式下仍能正常工作。
- 复位和低功耗唤醒可配。
- 使能看门狗后,当递减计数器达到0x000 时产生系统复位。
从上面的功能框图可以看出 IWDG 功能处于 VDD 供电区,在待机和深度睡眠模式下仍能正常工作。
配置寄存器(IWDG_KEY)为 0xCCCC 即可开启 IWDG,计数器开始递减计数。当计数达到 0x000 时,产生系统复位(IWDG_RESET)。为阻止看门狗复位,可在任意时刻配置寄存器 IWDG_KEY 为 0xAAAA,将 IWDG_RELV 的数据重新加载到计数器中。看门狗超时时间可以根据用户的需求通过设置寄存器 PREDIV[2:0] 来设置时间。 LSI 为 40KHz 的时候 PREDIV[2:0] 与时间的对应关系如下表所示。
在程序中,IWDG 的启用流程如下:
/* 1. Enable the LSI OSC */
RCC_EnableLsi(ENABLE);
while (RCC_GetFlagStatus(RCC_FLAG_LSIRD) == RESET) /* Wait till LSI is ready */
{}
/* 2. Enable write access to IWDG_PR and IWDG_RLR registers */
IWDG_WriteConfig(IWDG_WRITE_ENABLE); /* IWDG timeout equal to 250 ms (the timeout may varies due to LSI frequency dispersion) */
/* 3. Set the PREDIV[2:0] */
IWDG_SetPrescalerDiv(IWDG_PRESCALER_DIV32); /* IWDG counter clock: LSI/32 */
/* 4. Set counter reload value to obtain 250ms IWDG TimeOut */
/*Counter Reload Value = 250ms/IWDG counter clock period
= 250ms / (1/(LSI/32))
= 0.25s / (1/(LsiFreq/32))
= LsiFreq/(32 * 4)
= LsiFreq/128
*/
IWDG_CntReload(LsiFreq / 128);
/* 5. Reload IWDG counter */
IWDG_ReloadKey();
/* 6. Enable IWDG (the LSI oscillator will be enabled by hardware) */
IWDG_Enable();
/* 7. Reload IWDG counter at set intervals*/
IWDG_ReloadKey();
2、窗口看门狗(WWDG)
窗口看门狗(WWDG)的时钟由APB1 时钟分频而来,通过时间窗口的配置来检测程序操作是否异常。因此,WWDG 适用于精确计时,通常用来监测由外部干扰或不可预见的逻辑条件造成的应用程序背离正常的运行序列而产生的软件故障。WWDG的递减计数器在达到窗口寄存器数值之前或在T6位变成0 后被刷新,会产生中断或系统复位。WWDG 主要性能如下:
- 7 位独立运行递减计数器可编程
- WWDG 使能后,在以下条件产生复位:
- 提前唤醒中断:如果启动了看门狗并且使能中断,当计数值达到0x40 时产生唤醒中断(EWINT)
如果使能看门狗(WWDG_CTRL 寄存器中的ACTB 位被置‘1’),当7 位(T[6:0])递减计数器达到0x3F(T6位清零),或软件在计数器值大于窗口寄存器的数值时重新装载计数器,都将产生系统复位。为避免系统复位,软件在正常运行过程中必须定期地在窗口内刷新计数器值。
WWDG_CTRL 寄存器的 ACTB 位置‘1’使能看门狗,此后,除非发生复位,WWDG 将一直处于开启状态。7 位递减计数器处于独立运行状态,无论WWDG 使能与否,计数器均保持递减计数。因此,使能看门狗前 T6 位始终置‘1’,避免立即产生复位。T[5:0] 决定了两次重装载之间的最大时间间隔。时钟APB1 和WWDG_CFG 寄存器TIMERB[1:0] 设定的预分频值决定了计数器的递减速度。W[6:0] 设置窗口的上限值。
WWDG_CFG 寄存器的EWINT 位置‘1’使能提前唤醒中断。当递减计数器到达0x40 时产生中断,可以在相应的中断服务程序(ISR)中分析软件故障原因或保存重要数据,同时重新装载计数器以防止WWDG 复位。WWDG_STS 寄存器的EWINTF 位写‘0’可以清除该中断。
计算窗口看门狗超时时间的公式如下:
TWWDG = TPCLK1 × 4096 × 2TIMERB × (T[5: 0] + 1); (ms)
在程序中,WWDG 的启用流程如下:
/* 1. Enable WWDG clock */
RCC_EnableAPB1PeriphClk(RCC_APB1_PERIPH_WWDG, ENABLE);
/* 2. Set Prescaler Divider */
WWDG_SetPrescalerDiv(WWDG_PRESCALER_DIV8); /* WWDG clock counter = (PCLK1(36MHz)/4096)/8 = 1099 Hz (~910 us) */
/* 3. Set Window value to 80; WWDG counter should be refreshed only when the counter
is below 80 (and greater than 64) otherwise a reset will be generated */
WWDG_SetWValue(80);
/* 4. Enable WWDG and set counter value to 127, WWDG timeout = ~910 us * 64 = 58.25 ms
In this case the refresh window is: ~910 us * (127-80) = 42.77 ms < refresh window < ~910 us * 64 = 58.25ms
*/
WWDG_Enable(127);
/* 5. Update WWDG counter at set intervals */
WWDG_SetCnt(127);
以上流程为 WWDG 直接复位 MCU,若想打开提前唤醒中断,则需要用函数 WWDG_EnableInt() 设置 WWDG 的配置寄存器(WWDG_CFG) 的 bit9 (EWINT)为 1。在 WWDG 的中断处理函数(WWDG_IRQHandler)中可以做如下处理:
经过以上的说明,相信您已经对看门狗定时器以及如何使用国民技术 MCU 中的看门狗定时器有所了解。如果您感兴趣的话,可以在代码中添加看门狗功能,看看效果吧!欢迎在评论区交流您的经验。
参考资料
- 国民技术通用 MCU 用户手册。
评论