GD32E103C8T6《调试篇》之看门狗
看门狗定时器(WDGT)
1、知识点
看门狗定时器(WDGT)是一个硬件计时电路,用来监测由软件故障导致的系统故障。片上有
两个看门狗定时器外设,独立看门狗定时器(FWDGT)和窗口看门狗定时器(WWDGT)。
它们使用灵活,并提供了很高的安全水平和精准的时间控制。两个看门狗定时器都是用来解决
软件故障问题的。
看门狗定时器在内部计数值达到预设门限的时候,会触发一个复位。当处理器工作在调试模式
的时候看门狗定时器定时计数器可以停止计数。
这两段来自用户手册。
————————————————————
独立看门狗的原理:设定一个重载值。赋值计数器。每来一个脉冲计数值减减。如果计数值减到0。还没有去喂狗就会产生复位。所以在计数值在0~重载值范围必须要喂一次狗。
在键值寄存器(IWDG_KR)中写入0xCCCC,开始启用独立看门狗。此时计数器开始从其复位值0xFFF递减,当计数器值计数到尾值0x000时会产生一个复位信号(IWDG_RESET)。
无论何时,只要在键值寄存器IWDG_KR中写入0xAAAA(通常说的喂狗), 自动重装载寄存器IWDG_RLR的值就会重新加载到计数器,从而避免看门狗复位。
如果程序异常,就无法正常喂狗,从而系统复位。
2、代码
#include "common.h"
//485 PB10--Tx PB11--Rx
//ADC PA0
ts_uart logo;
volatile uint16_t adcValue = 0;//
volatile uint16_t volValue = 0;//
void usart2_init() // 初始化串口0
{
rcu_periph_clock_enable(RCU_GPIOB); // 使能GPIOA时钟
rcu_periph_clock_enable(RCU_USART2); // 使能串口0时钟
/* connect port to USARTx_Tx *///配置TX 推挽复用模式
gpio_init(GPIOB, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_10);
/* connect port to USARTx_Rx *///配置RX 浮空输入模式
gpio_init(GPIOB, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_11); //
/***** 485 TX enable ****/ //pin19--PB1
gpio_init(GPIOB, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_1); //GPIO_OSPEED_2MHZ
gpio_bit_set(GPIOB,GPIO_PIN_1); //0-Rx
// 步骤1-7:
usart_deinit(USART2);
usart_word_length_set(USART2,USART_WL_8BIT); ///2、配置USART字长
usart_stop_bit_set(USART2,USART_STB_1BIT); ///3、配置USART停止位
usart_baudrate_set(USART2,115200); ///5、配置USART波特率
usart_transmit_config(USART2,USART_TRANSMIT_ENABLE); // 6、USART发送配置
usart_receive_config(USART2,USART_RECEIVE_ENABLE);
usart_enable(USART2);//使能串口
// 在nvic中配置中断向量和中断优先级
nvic_irq_enable(USART2_IRQn,0,0); //使能NVIC的中断
// 使能USART子中断
usart_interrupt_enable(USART2,USART_INT_RBNE);
// usart_interrupt_enable(USART2,USART_INT_RT);
}
int main(void)
{
systick_config(); //初始化延时函数
delay_ms(100);
usart2_init();
fwdg_init();//初始化独立看门狗
printf("Independent watchdog \r\n");
while(1)
{
feed_dog();//喂狗
printf("Feed the dog \r\n");
delay_ms(1000);
}
}
/**
@brief 初始化独立看门狗
@param 超时时间:Tout=(pre*reload)/40000(s)
pre:重装载计数值 取值范围:0~0xFFF.(最大值:4095)
reload:预分频系数 取值范围:[4,8,16,32,64,128,256]
@return 无
*/
void fwdg_init(void)
{
//开启时钟源(IRC40K),并等待其稳定以供看门狗使用
rcu_osci_on(RCU_IRC40K);//开启IRC40k 默认就是 IRC40k的时钟
while(SUCCESS != rcu_osci_stab_wait(RCU_IRC40K))
{
} //等待IRC40k稳定下来
/* configure FWDGT counter clock: 40KHz(IRC40K) / 64 = 0.625 KHz */
fwdgt_config(2 * 500, FWDGT_PSC_DIV64);
/* after 1.6 seconds to generate a reset */
fwdgt_enable();
/* check if the system has resumed from FWDGT reset */
if(RESET != rcu_flag_get(RCU_FLAG_FWDGTRST)){
/* clear the FWDGT reset flag */
rcu_all_reset_flag_clear();
}
}
/* feed dog 1/(40/64)=1.6 1.6*1000 = 1600ms */
void feed_dog(void)
{
fwdgt_counter_reload();//6.4s内不喂狗将重启
}
// 中断处理函数
void USART2_IRQHandler(void)
{
if( RESET != usart_interrupt_flag_get(USART2,USART_INT_FLAG_RBNE) )// 发生中断,则返回RESET
{
usart_data_receive(USART2); // 读取串口2接收到的数据
}
usart_interrupt_flag_clear(USART2, USART_INT_FLAG_EB);
}
/* retarget the C library printf function to the USART */
int fputc(int ch, FILE *f)
{
usart_data_transmit(USART2, (uint8_t)ch);
while(RESET == usart_flag_get(USART2, USART_FLAG_TBE));
return ch;
}
3、效果
喂狗,工作正常;
注释喂狗,芯片就会不断重启,时间大概1.6s,验证成功;
USART