本帖最后由 御坂10032号 于 2024-7-1 02:45 编辑
本章我们要测试的时GD32H759I-EVAL的独立看门狗功能。
简介
看门狗定时器(WDGT)是一个硬件计时电路,用来监测由软件故障导致的系统故障。片上有两个看门狗定时器外设, 独立看门狗定时器(FWDGT)和窗口看门狗定时器(WWDGT)。它们使用灵活,并提供了很高的安全水平和精准的时间控制。两个看门狗定时器都是用来解决软件故障问题的。
独立看门狗定时器(FWDGT)有独立时钟源(IRC32K)。因此,即使主时钟失效了,它仍然能保持工作状态,这非常适合于需要独立环境且对计时精度要求不高的场合。
当内部向下计数器的计数值达到0或计数器的值大于窗口寄存器的值,刷新计数器, 独立看门狗会产生一个复位。使能独立看门狗的寄存器写保护功能可以避免寄存器的值被意外的配置篡改。
根据GD32H7用户手册的第599页我们得知。 简要来说看门狗就是一个硬件复位电路。使用独立的时钟源提供给看门狗内部的计数器。当设置的计数器递减到0的时候,便会产生一个复位。
那么为了避免在系统运行正常时产生复位,那么就需要程序在计数器递减到0之前来`喂狗` (重置计数器),从而保证程序不会出错。
了解完开门狗的工作原理之后。我们可以看一下如何设置看门狗的时间。IRC32K的时钟,经过分频经过最高12位的计数器进行递减。 如果减到0的话则产生复位。
下图为IRC32K时钟在不同分频下,的最小和最大计时时间(即喂狗时间)
那么我们来看下程序怎么编码。
初始化看门狗:
void init_fwdgt(void)
{
//使用RCU_IRC32K 作为独立看门狗的时钟
rcu_osci_on(RCU_IRC32K);
// 等待时钟稳定
while(SUCCESS != rcu_osci_stab_wait(RCU_IRC32K));
//开启写
fwdgt_write_enable();
//设置时钟分频
fwdgt_prescaler_value_config(FWDGT_PSC_DIV64);
//设置看门狗的复位时间
fwdgt_reload_value_config(0x0FFF);
//关闭写
fwdgt_write_disable();
//开启独立看门狗
fwdgt_enable();
}
喂狗
void feed_dog(void)
{
//开启写
fwdgt_write_enable();
//喂狗,重载Counter
fwdgt_counter_reload();
//关闭写
fwdgt_write_disable();
}
这里需要注意的一点就是设置看门狗的时钟分频以及时钟的装载值。可以根据上述的表格进行确定和计算。
完整代码如下
#include "gd32h7xx.h"
#include "systick.h"
#include "bsp_usart.h"
static void cache_enable(void)
{
/* Enable I-Cache */
SCB_EnableICache();
/* Enable D-Cache */
SCB_EnableDCache();
}
extern uint8_t usart0_receive_data;
void init_fwdgt(void)
{
//使用RCU_IRC32K 作为独立看门狗的时钟
rcu_osci_on(RCU_IRC32K);
// 等待时钟稳定
while(SUCCESS != rcu_osci_stab_wait(RCU_IRC32K));
//开启写
fwdgt_write_enable();
//设置时钟分频
fwdgt_prescaler_value_config(FWDGT_PSC_DIV64);
//设置看门狗的复位时间
fwdgt_reload_value_config(0x0FFF);
//关闭写
fwdgt_write_disable();
//开启独立看门狗
fwdgt_enable();
}
void feed_dog(void)
{
//开启写
fwdgt_write_enable();
//喂狗,重载Counter
fwdgt_counter_reload();
//关闭写
fwdgt_write_disable();
}
int main(void)
{
cache_enable();
systick_config();
usart_init();
usart_receive_init();
init_fwdgt();
if(RESET != rcu_flag_get(RCU_FLAG_FWDGTRST)) {
rcu_all_reset_flag_clear();
printf("RCU_FLAG_FWDGTRST reset\r\n");
while(1) {
}
}
while(1) {
delay_1ms(8000);
feed_dog();
}
}
上述代码设置的时钟分频为64分频,那么根据用户手册我们得知,如果64分频的话,那么看门狗会在8192ms的时候复位系统。所以只要我们在8192秒之内喂狗的话,那么系统就不会复位
喂狗成功实验现象
实验正常,串口一直没有输出,因为程序在8192ms内执行了喂狗操作。
我们将主循环中的延时操作修改一下。比如说8193ms。再进行测试
喂狗失败,实验现象
此时会发现,由于喂狗的时间大于8192ms,那么独立看门狗触发了复位,系统复位。
附件:
|