STM32·HAL库开发(十二)IWDG独立看门狗——案例:按键喂狗

目录

【看门狗简述】

【独立看门狗】

【独立看门狗框图】

【独立看门狗时钟】

【预分频寄存器IWDG_PR】

        分频系数计算公式:

【重装载寄存器IWDG_RLR】

【键寄存器IWDG_KR】

         溢出时间计算公式:

【demo · IWDG_KEY_USART】


【看门狗简述】

        在由单片机构成的微型计算机系统中,由于单片机的工作常常会受到来自外界电磁场的干扰,造成程序的跑飞,从而陷入死循环,程序的正常运行被打断,由单片机控制的系统无法继续工作,会造成整个系统的陷入停滞状态。
        出于对单片机运行状态进行实时监测的考虑,便产生了一种专门用于监测单片机程序运行状态的模块或者芯片,俗称“看门狗 ” (watchdog) 。

【独立看门狗】

        独立看门狗工作在主程序之外,能够完全独立工作,它的时钟是专用的低速时钟( LSI ),由 VDD 电压供电, 在停止模式和待机模式下仍能工作。
         独立看门狗 本质 是一个 12 位的递减计数器 ,当计数器的值从某个值一直减到0 的时候,系统就会产生一个复位信号,即 IWDG_RESET 。 如果在计数没减到0 之前,刷新了计数器的值的话,那么就不会产生复位信号,这个动作就是我们经常说的喂狗。
        独立看门狗主要用于检测硬件异常,窗口看门狗主要用于检测软件异常

【独立看门狗框图】

         喂狗是指在IWDG_RLR重装载寄存器中写值

【独立看门狗时钟】

        独立看门狗的时钟由独立的RC 振荡器 LSI 提供,即使主时钟发生故障它仍然有效,非常独立。启用IWDG后, LSI 时钟会自动开启。 LSI时钟频率并不精确,F140kHz
        LSI经过一个 8 位的预分频器得到计数器时钟。
        分频因子可以是:[4,8,16,32,64,128,256,256]

【预分频寄存器IWDG_PR】

        // 刊误:111时预分频因子为512

        分频系数计算公式:

        说明: prer即PR[2:0]的值,上表给出的预分频因子PSC是根据公式计算后的结果
        例:     PR[2:0] = 010 时,PSC = 4 × 2² = 16

【重装载寄存器IWDG_RLR】

         重装载寄存器 是一个12 位的寄存器,用于存放重装载值,低 12 位有效,即 最大值为4095 ,这个值的大小 决定独立看门狗的溢出时间

【键寄存器IWDG_KR】

         键寄存器 IWDG_KR 可以说是独立看门狗的一个 控制寄存器 ,主要有三种控制方式,往这个寄存器写入下面三个不同的值有不同的效果

         溢出时间计算公式:         

        计数器时钟(频率):F_IWDG / PSC
        计数器周期(完成一次所需时间):PSC / F_IWDG
        溢出时间(一次时间×次数):T_out = (PSC * (RLR+1))  / F_IWDG
        F_IWDG即LSI,40kHz

最长时间:RLR为4095,T_out = ((256)*(4095+1)) / 40000 = 26.2144 s

【demo · IWDG_KEY_USART】

        项目概述:开启独立看门狗,溢出时间为1秒,使用按键1进行喂狗

        接线:KEY(按下高电平)——PA1        USART1——PA9 、PA10

        溢出时间:PSC=64RLR=624     T_out = (64*624) / (40×1000) = 1 s

        在CubeMX_USART_NVIC基础上修改(增加IWDG,KEY)

初始化函数(CubeMX自动生成):

MX_IWDG_Init();

喂狗函数:

HAL_IWDG_Refresh(&hiwdg);
/* main.c */

int main(void)
{
    HAL_Init();
    SystemClock_Config();
    MX_GPIO_Init();
    MX_USART1_UART_Init();
    MX_IWDG_Init();

	HAL_UART_Receive_IT(&huart1, &buf, 1);
	printf("若未喂狗则反复启动,打印该行,若程序正常运行可回显串口数据\r\n");
    //HAL_Delay(1000);

    while (1)
    {
	    if(HAL_GPIO_ReadPin(KEY_GPIO_Port, KEY_Pin) == GPIO_PIN_SET)
			HAL_IWDG_Refresh(&hiwdg);
		HAL_Delay(50);
		if(UART1_RX_STA & 0x8000)
		{
			printf("收到数据:");														// 把“”中的内容打印到串口
			printf("%s",UART1_RX_Buffer);			// 将收到的数据发送到串口
			//HAL_UART_Transmit(&huart1, UART1_RX_Buffer, UART1_RX_STA & 0x3fff, 0xffff);		// 将收到的数据发送到串口
			while(huart1.gState != HAL_UART_STATE_READY);		// 等待发送完成
			printf("\r\n");
			UART1_RX_STA = 0;																// 重新开始下一次接收
			memset(UART1_RX_Buffer,0,sizeof(UART1_RX_Buffer));	// 清空缓冲区
		}
  }

}

注意:

        若在程序中加入了        HAL_Delay(1000);        喂狗一定失败
        因为需要在1s内进行喂狗,但是延时时间已经1s了,无法及时喂狗
        实测        HAL_Delay(500);         时可喂狗成功

参考:STM32 HAL库 STM32CubeMX -- IWDG(独立看门狗)_cubemx看门狗_Dir_xr的博客-优快云博客

【标准库代码】

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "Key.h"

int main(void)
{
	/*模块初始化*/
	OLED_Init();						//OLED初始化
	Key_Init();							//按键初始化
	
	/*显示静态字符串*/
	OLED_ShowString(1, 1, "IWDG TEST");
	
	/*判断复位信号来源*/
	if (RCC_GetFlagStatus(RCC_FLAG_IWDGRST) == SET)	//如果是独立看门狗复位
	{
		OLED_ShowString(2, 1, "IWDGRST");			//OLED闪烁IWDGRST字符串
		Delay_ms(500);
		OLED_ShowString(2, 1, "       ");
		Delay_ms(100);
		
		RCC_ClearFlag();							//清除标志位
	}
	else											//否则,即为其他复位
	{
		OLED_ShowString(3, 1, "RST");				//OLED闪烁RST字符串
		Delay_ms(500);
		OLED_ShowString(3, 1, "   ");
		Delay_ms(100);
	}
	
	/*IWDG初始化*/
	IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);	//独立看门狗写使能
	IWDG_SetPrescaler(IWDG_Prescaler_16);			//设置预分频为16
	IWDG_SetReload(2499);							//设置重装值为2499,独立看门狗的超时时间为1000ms
	IWDG_ReloadCounter();							//重装计数器,喂狗
	IWDG_Enable();									//独立看门狗使能
	
	while (1)
	{
		Key_GetNum();								//调用阻塞式的按键扫描函数,模拟主循环卡死
		
		IWDG_ReloadCounter();						//重装计数器,喂狗
		
		OLED_ShowString(4, 1, "FEED");				//OLED闪烁FEED字符串
		Delay_ms(200);								//喂狗间隔为200+600=800ms
		OLED_ShowString(4, 1, "    ");
		Delay_ms(600);
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值