stm32学习笔记-14 看门狗

14 WDG看门狗

14.1.1 WDG简介

•WDG(Watchdog)看门狗

目的:看门狗可以监控程序的运行状态,当程序因为设计漏洞、硬件故障、电磁干扰等原因,出现卡死或跑飞现象时,看门狗能及时复位程序,避免程序陷入长时间的罢工状态,保证系统的可靠性和安全性。

它只能帮你避免一下没有预料的漏洞,但不能解决漏洞,所以还是要在写代码时就想好可能会出现的问题。

运行逻辑:看门狗本质上是一个定时器,当指定时间范围内,程序没有执行喂狗(重置计数器)操作时,看门狗硬件电路就自动产生复位信号。

硬件配置:STM32内置两个看门狗
独立看门狗(IWDG):独立工作,对时间精度要求较低
窗口看门狗(WWDG):要求看门狗在精确计时窗口起作用

14.2.1 IWDG 独立看门狗

在这里插入图片描述

时钟:LSI内部低速40kHz时钟

预分频:8位最大256分频

递减计数器:12位最大4095计数

重装载寄存器:12位最大4095重装值

状态寄存器:只有两个更新同步位

键寄存器:写入特殊值控制电路重装计数器(喂狗)

当自减到0,下一个时钟脉冲重装计数值,产生IWDG复位。

看门狗处于VDD供电区,停机和待机仍能正常工作。

14.2.2 IWDG 键寄存器

在这里插入图片描述

  • 键寄存器本质上是控制寄存器,用于控制硬件电路的工作

  • 在可能存在干扰的情况下,一般通过在整个键寄存器写入特定值来代替控制寄存器写入一位的功能,以降低硬件电路受到干扰的概率

14.2.3 IWDG 超时时间

在这里插入图片描述

•超时时间:TIWDG = TLSI × PR预分频系数 × (RL + 1)

•其中:TLSI = 1 / FLSI

最长时间就是重装载值给最大

14.3.1 WWDG 窗口看门狗

在这里插入图片描述

PCLK1:APB1的时钟36MHz。

递减计数器:只有T0~T5是有效值,T6是溢出标志位。所以写的是6位自减计数器。

当然也有两种不同的溢出方式计算,如果你把T6当作溢出标志位则T0~T5减到0下一个脉冲溢出,如果你把T6当作计数位那么整个计数器减到0x40(01000000)之后下一个脉冲溢出即0x3F。(下面会出现这两种描述方法,需要理解一下)

但没有重装载寄存器,想要装载就需要自己手动填值。

WDGA位:使能看门狗,1使能。

WWDG_CFR:喂狗的最早时间界限。

14.3.2 WWDG工作特性

在这里插入图片描述
•递减计数器T[6:0]的值小于0x40时,WWDG产生复位

•递减计数器T[6:0]在窗口W[6:0]外被重新装载时,WWDG产生复位

•递减计数器T[6:0]等于0x40时可以产生早期唤醒中断(EWI),用于重装载计数器以避免WWDG复位

•定期写入WWDG_CR寄存器(喂狗)以避免WWDG复位

14.3.3 WWDG超时时间

在这里插入图片描述
PCLK1在进入WWDG时会固定分一个4096分频。

分频系数只能时0~3。

14.3.4 IWDG和WWDG的对比

在这里插入图片描述

tips:硬件看门狗:在选项字节里设置,硬件上电自动开启看门狗,防止在开启看门狗之前就程序卡死。

14.4.1 IWDG

由于代码较少不封装,仅展示main.c

#include "stm32f10x.h"      
#include "Delay.h"
#include "OLED.h"
#include "Key.h"

int main(void)
{
	OLED_Init();
	Key_Init();
	
    //获取标志位判断是复位键复位还是看门狗复位
	if(RCC_GetFlagStatus(RCC_FLAG_IWDGRST)==SET)
	{
		OLED_ShowString(1,1,"IWDGRST");
		Delay_ms(500);
		OLED_ShowString(1,1,"       ");
		Delay_ms(100);
		RCC_ClearFlag();
	}
	else
	{
		OLED_ShowString(2,1,"RST");
		Delay_ms(500);
		OLED_ShowString(2,1,"   ");
		Delay_ms(100);	
	}
	
    //解除写保护
	IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);
    //设置预分频值
	IWDG_SetPrescaler(IWDG_Prescaler_16);
    //设置重装值
	IWDG_SetReload(2499);
    //喂狗,使第一次喂狗周期是1s
	IWDG_ReloadCounter();
    //开启看门狗,会自动打开LSI时钟,不需要我们开启
	IWDG_Enable();

	while (1)
	{
        //获取键码值导致超时喂狗
		Key_GetNum();

        //喂狗
		IWDG_ReloadCounter();
		OLED_ShowString(3,1,"FEED");
		Delay_ms(600);
		OLED_ShowString(3,1,"    ");
		Delay_ms(330);
	}
}

喂狗和使能看门狗后,会自动给键寄存器写0x5555之外的值,开启写保护。所以我们不用手动给写保护。

14.5.1 WWDG

由于代码较少不封装,仅展示main.c

#include "stm32f10x.h"      
#include "Delay.h"
#include "OLED.h"
#include "Key.h"

int main(void)
{
	OLED_Init();
	Key_Init();
	
     //获取标志位判断是复位键复位还是看门狗复位
	if(RCC_GetFlagStatus(RCC_FLAG_WWDGRST)==SET)
	{
		OLED_ShowString(1,1,"WWDGRST");
		Delay_ms(500);
		OLED_ShowString(1,1,"       ");
		Delay_ms(100);
		RCC_ClearFlag();
	}
	else
	{
		OLED_ShowString(2,1,"RST");
		Delay_ms(500);
		OLED_ShowString(2,1,"   ");
		Delay_ms(100);	
	}
	
	//由于WWDG是APB1的时钟所以需要手动开启
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG,ENABLE);
    //设置预分频
	WWDG_SetPrescaler(WWDG_Prescaler_8);
    //设置窗口时间
	WWDG_SetWindowValue(0x40 | 21);
    //使能WWDG并第一次喂狗
	WWDG_Enable(0x40 | 54);
	

	while (1)
	{
		Key_GetNum();

		OLED_ShowString(3,1,"FEED");
		Delay_ms(20);
		OLED_ShowString(3,1,"    ");
		Delay_ms(20);
		//喂狗
		WWDG_SetCounter(0x40 | 54);
	}
}
  • 由于使能时会喂狗,所以第二次喂狗要放在延时函数之后否则就会导致快速喂狗。

  • 因为看门狗不开启时,自减计数器也在运行,所以使能函数中就包含了第一次喂狗的函数。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值