前言
当你用一款单片机开发具体产品的时候,为了保证软件的可靠性,除了一系列的框架与流程图等等,也需要有类似定时检查的机制,去保证我们的MCU在正常按照你的软件逻辑在运行,这就是我们单片机功能中的看门狗模块。
看门狗
一、介绍
看门狗定时器(WDGT)是一个硬件计时电路,用来监测由软件故障导致的系统故障。片上有两个看门狗定时器外设,独立看门狗定时器(FWDGT)和窗口看门狗定时器(WWDGT)。它们使用灵活,并提供了很高的安全水平和精准的时间控制。两个看门狗定时器都是用来解决
软件故障问题的。
看门狗定时器在内部计数值达到了预设的门限的时候,会触发一个复位(对于窗口看门狗定时器来说,会产生一个中断)。当处理器工作在调试模式的时候看门狗定时器定时计数器可以停止计数。
————以上摘自GD32F303用户手册看门狗定时器章节
二、区别
两者所做的最终目的都是同一件事——定时检查,异常的情况下自动复位。区别在于,两者的时钟源不同。
独立看门狗:时钟源来自于内部低速时钟。所以即使主时钟失效,亦能保证产生复位。但计数精度不高。
窗口看门狗:时钟源来自于APB1时钟预分频。这样保证了计数精确,但主时钟失效,它也跟着失效。
对绝大多数产品而言,我们需要的看门狗还是定时检查然后复位的功能,计数精度并不是特别重要(如1s变成1.01s)。本文给出的示例代码也是配置独立看门狗的。
各模块程序编写
在配置前,请确保你已经有一个GD32F303包含其对应标准库的keil工程,工程可使用官方的例程或可按照GD32F303调试小记(零)之工程创建与编译创建。
一、独立看门狗定时器框图
二、注意事项
- 重点都在上述图中红框框出来的部分了,这里不多做解释。
三、初始化配置
void FWDGT_Init(void)
{
uint16_t timeout_t=0xFFFFU;
/* enable IRC40K */
rcu_osci_on(RCU_IRC40K);
/* wait till IRC40K is ready */
while(SUCCESS != rcu_osci_stab_wait(RCU_IRC40K))
{
if(timeout_t > 0) timeout_t--;
else break;
}
/* configure FWDGT counter clock: 40KHz(IRC40K) / 64 = 0.625 KHz */
fwdgt_config(2*500,FWDGT_PSC_DIV64); //t = (1/0.625)x(2x500) = 1.6s
fwdgt_write_disable();
/* After 1.6 seconds to generate a reset */
fwdgt_enable();
}
- 开启内部低速时钟、等待稳定、配置看门狗定时器分频系数和重载计数值、开启看门狗寄存器写保护功能,开启开门狗定时器。
四、主函数
1. 创建喂狗任务
- 关闭看门狗写保护,重载计数值。
void task_fwdgt_reload(void)
{
/* uncock fwdgt write protect*/
fwdgt_write_enable();
/* feed fwdgt */
fwdgt_counter_reload();
}
2. 主函数
- 你可以喂狗任务作为在调度系统中的一个子任务,也可以在纯裸机中最大的循环里作为每次必做的事,像这样:
int main(void)
{
FWDGT_Init();
while(1)
{
task_fwdgt_reload();
}
}
3. 其它
- 看门狗一旦开启后,无法关闭。不过可以修改重装载值,即人为的使看门狗溢出,让整个软件系统复位。如下:
/* 某种条件触发 */
if(something)
{
/* 重新配置看门狗计数值 */
fwdgt_write_enable();
/* configure FWDGT counter clock: 40KHz(IRC40K) / 64 = 0.625 KHz */
fwdgt_config(5,FWDGT_PSC_DIV64); //t = (1/0.625)x(5) = 8ms
fwdgt_counter_reload();
fwdgt_enable();
}