当前位置: 首页 > article >正文

基于STM32F407ZGT6——看门狗

独立看门狗

        独立看门狗的时钟由独立的RC 振荡器LSI 提供,即使主时钟发生故障它仍然有效,非常独立。 LSI 的频率一般在30~60KHZ 之间,根据温度和工作场合会有一定的漂移, 所以独立看门狗的定时时间并不一定非常精确,只适用于对时间精度要求比较低的场合。(需要注意独立看门狗的时钟并不是准确的 32Khz, 而是在 15~47Khz之间的一个可变化的时钟 )

1.计数器时钟

        递减计数器的时钟由LSI 经过一个8 位的预分频器得到,我们可以操作预分频器寄存器 IWDG_PR 来设置分频因子,分频因子可以是:[4,8,16,32,64,128,256]

计数器时钟CK_CNT= 40/ 4*2^PRV,一个计数时钟到来,计数器就减一。

(置位110和111都是256分频)        

2.重装载计数器

        重装载寄存器是一个12 位的寄存器,里面装着要刷新到计数器的值,这个值的大小决定着独立 看门狗的溢出时间。超时时间Tout = (4*2^prv) / 40 * rlv (s) ,prv 是预分频器寄存器的值,rlv 是 重装载寄存器的值。

3.键寄存器IWDG_KR

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

4.独立看门狗代码

#include "iwdg.h"

/*
	1.取消写保护 IWDG_WriteAccessCmd   0x5555
	2.对LSI时钟分频,32分频  32khz/32=1khz  计一个数:1/1khz = 1ms
		IWDG_SetPrescaler
	3.设置看门狗溢出时间:重装载寄存器值
		IWDG_SetReload
	4.填充自动重装载值
		IWDG_ReloadCounter
	5.使能看门狗
		IWDG_Enable
	6.在程序中定时喂狗
		按键喂狗:判断按键按下后调用IWDG_ReloadCounter
*/
void IWDG_Init_Config(void)
{
	//取消写保护
	
	IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);
	
	//设置分频系统
	IWDG_SetPrescaler(IWDG_Prescaler_32); 
	//32分频  32khz/32=1khz  倒数一个数:1/1khz = 1/1000hz =0.001s = 1ms
	
	//设置重装载值
	IWDG_SetReload(2000-1);  //数2000个数,用时2s
	IWDG_ReloadCounter();
	
	//启动
	IWDG_Enable();

}
#include "stm32f4xx.h"
#include "uart.h"
#include "led.h"
#include "stdio.h"
#include "timer.h"
#include "pwm.h"
#include "delay.h"
#include "iwdg.h"
int main(void)
{
		//2号分组:2bit给抢占  2bit给响应   0-3  0-3 
		NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); 

		key_init();	
		LED0_init();
		GPIO_ResetBits(GPIOF,GPIO_Pin_9); //如果复位,则灯亮

		SysTick_Init(); //系统延时
		//f = 84Mhz/ (83+1)  / (999+1)  = 1Khz
		//pwm频率 = 时钟频率/(分频值+1)/(自动重装载值+1)
		tim13_pwm_led0(84, 3816);
		IWDG_Init_Config();

        delay_ms(30);
		WWDG_SetCounter(0x7f);//窗口看门狗的上限最大值是0x7F,也就是最大值是127,我们自己设置上限,取值在64-127之间,64是0x40,是寄存器内部设置的
		//改变灯的状态
		GPIO_ToggleBits(GPIOF,GPIO_Pin_9|GPIO_Pin_10);
				
    }

窗口看门狗

        窗口看门狗跟独立看门狗一样,也是一个递减 计数器不断的往下递减计数,当减到一个固定值0X40 时还不喂狗的话,产生复位,这个值叫窗 口的下限,是固定的值,不能改变。

        这是跟独立看门狗类似的地方,不同的地方是窗口看门狗 的计数器的值在减到某一个数之前喂狗的话也会产生复位,这个值叫窗口的上限,上限值由用户 独立设置。窗口看门狗计数器的值必须在上窗口和下窗口之间才可以喂狗,这就是窗口看门狗中 窗口两个字的含义。

        T[6:0]就是 WWDG_CR的低七位, W[6:0]即是 WWDG-->CFR的低七位。 T[6:0]就是窗口看门狗的计数器,而 W[6:0]则是窗口看门狗的上窗口,下窗口值是固定的( 0X40)。

        当窗口看门狗的计数器在上窗口值之外被刷新,或者低于下窗口值都会产生复位。 上 窗口值 W[6: 0] 是由用户自己设定的,根据实际要求来设计窗口值,但是一定要确保 窗口值大于 0X40,否则窗口就不存在了

        窗口看门狗时钟来自PCLK1,PCLK1 最大是42M,由RCC 时钟控制器开启。

        计数器时钟由CK 计时器时钟经过预分频器分频得到,分频系数由配置寄存器CFR 的WDGTB[1:0] 配置。其中CK 计时器时钟=PCLK1/4096,除以4096 是手 册规定的,手册没有解释为什么(个人猜测还是为了降频)。所以计数器的时钟CNT_CK=PCLK1/4096/(2^WDGTB),这就可以算出 计数器减一个数的时间T= 1/CNT_CK = 4096 * (2^WDGTB) / PCLK1。

        窗口看门狗的计数器是一个递减计数器,共有7 位,其值存在控制寄存器CR 的位6:0,即T[6:0], 当7 个位全部为1 时是0X7F,这个是最大值,当递减到T6 位变成0 时,即从0X40 变为0X3F 时候,会产生看门狗复位。这个值0X40 是看门狗能够递减到的最小值,所以计数器的值只能是: 0X40~0X7F 之间。(64~127)

        当递减计数器递减到0X40 的时候,还不会马上 产生复位(再减一次就复位),如果使能了提前唤醒中断:CFR 位9 EWI 置1,则产生提前唤醒中断,如果真进入了 这个中断的话,就说明程序肯定是出问题了,那么在中断服务程序里面我们就需要做最重要的工 作,比如保存重要数据,或者报警等,这个中断我们也叫它死前中断。

        窗口看门狗必须在计数器的值在一个范围内才可以喂狗,其中下窗口的值是固定的 0X40,上窗口的值可以改变,具体的由配置寄存器CFR 的位6:0 W[6:0] 设置。其值必须大于 0X40,如果小于或者等于0X40 就是失去了窗口的价值,而且也不能大于计数器的值,所以必须 得小于0X7F。

        那窗口值具体要设置成多大?这个得根据我们需要监控的程序的运行时间来决定。 如果我们要监控的程序段A 运行的时间为Ta,当执行完这段程序之后就要进行喂狗,如果在窗 口时间内没有喂狗的话,那程序就肯定是出问题了。一般计数器的值TR 设置成最大0X7F,窗 口值为WR,计数器减一个数的时间为T,那么时间:(TR-WR)*T 应该稍微小于Ta 即可,这样 就能做到刚执行完程序段A 之后喂狗,起到监控的作用,这样也就可以算出WR 的值是多少。

  1. 计数器初始值: WWDG在启动时,计数器的初始值被设定为窗口上限值。

  2. 计数值递减: 计数器的数值递减,不断减小。

  3. 窗口上限值: 窗口上限值是一个阈值,当计数器的值大于窗口上限值时,WWDG可以产生中断。

  4. 可产生中断: 在窗口期内,当计数器的值大于窗口上限值时,WWDG可以产生中断。这时,系统可以执行一些预定义的中断服务程序。

  5. 窗口下限值,产生复位: 当计数器的值小于等于窗口下限值时,WWDG将触发复位。窗口下限值是一个临界值,如果计数器的值在窗口期内没有被重载,则会导致复位。

  6. 窗口期,可以喂狗: 在窗口期内,如果计数器的值大于窗口下限值(0x3F),可以通过喂狗的方式重载计数器的值,防止触发复位。

  7. 非窗口期,喂狗则会复位: 如果计数器的值小于等于窗口下限值,表示已经超过了窗口期,此时喂狗将无效,WWDG将触发复位。

WWDG(窗口看门狗)的框图如下:

  1. 时钟源: PCLK(Peripheral Clock)是来自RCC(Reset and Clock Control)时钟控制器的时钟源。不同型号的STM32芯片,其PCLK的频率可能不同,例如,F103系列是36MHz,F407系列是42MHz,F429系列是45MHz,F767系列是54MHz,H743系列是100MHz,等等。

  2. 分频: 时钟源通过一个固定的分频系数(4096)进入WDG预分频器(WDGTB)。

  3. 递减计数器(CNT): WDGTB输出的时钟进入看门狗控制寄存器(WWDG_CR),其中T0到T5是一个6位的递减计数器,T6用于判断是否处于窗口期。

  4. 看门狗配置寄存器(WWDG_CFR): 该寄存器用于配置WWDG的一些参数,包括窗口上限值W[6:0]和比较器(COM)。

  5. 看门狗控制寄存器(WWDG_CR): 包含递减计数器的当前值T0-T5,判断位T6,激活位WDGA等。

  6. 比较器: 当T0到T5的值大于窗口上限值W[6:0]时,比较器输出为1。

  7. 喂狗操作: 通过写WWDG_CR寄存器,喂狗操作即将递减计数器的当前值重新加载到W[6:0],这样可以避免复位。在窗口期内有效,可以通过该操作刷新看门狗计数。

  8. 判断是否复位: 复位的判断条件包括T6为0和WDGA激活位为1,同时还要判断是否在窗口期内进行了喂狗操作。如果不在窗口期内进行喂狗或者T6为0,则WWDG将触发复位。

总的来说,WWDG的工作框图涉及到时钟源的分频、递减计数器、窗口配置、比较器、喂狗操作,以及复位的判断条件。这些都是为了保证WWDG的正常工作和对程序运行的监测。 WWDG超时时间计算

最大值怎么算出来的?(了解即可)

        例如WDGTB=0时,当计数值为0x40时,递减计数器再减一次,就产生复位 了,那这减1的时间就等于计数器的周期=1/CNT_CK = 4096 * (2^WDGTB)/PCLK1 = 1/30 * 4096 *2^0 =136.53us,这个就是最短的超时时间。

        如果T[5:0] 全部装满为1,即63,当他减到0X40 变 成0X3F 时,所需的时间就是最大的超时时间=136.532^6=136.5364=8.74ms。同理,当WDGTB 等于1/2/3 时,代入公式即可。

代码

#include "wwdg.h"
#include "stm32f4xx.h"
/*	
	1.APB1时钟使能
	2.时钟分频 42MHZ
		WWDG_SetPrescaler 
	3.设置窗口值
		WWDG_SetWindowValue
	4.窗口计数器使能
		WWDG_Enable
	5.需要定时喂狗
*/
//   上窗口前时间(127-100)*780us = 21.06ms
//		喂狗时间		(100-64)*780us = 28.08ms
void WWDG_Init_Config(void)
{
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, ENABLE);

	WWDG_SetPrescaler(WWDG_Prescaler_8);	//4分频, 42Mhz/ 4096 / 8 = 1281hz   计数计一个数时间为780us

	//0x7f - 0x40    127-64
	WWDG_SetWindowValue(100);
	
	WWDG_Enable(0x7f);

}
#include "public.h"

int main(void)
{
	//2号分组:2bit给抢占  2bit给响应   0-3  0-3 
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); 
	SysTick_Init();
	KEY_Init();	
	LED_Init();
	GPIO_ResetBits(GPIOF,GPIO_Pin_9); //如果复位,则灯亮
	
	WWDG_Init_Config();
	while(1)
	{
		Delay_ms(30);
		WWDG_SetCounter(0x7f);
		//改变灯的状态
		GPIO_ToggleBits(GPIOF,GPIO_Pin_9|GPIO_Pin_10);
	}	
}

总结

独立看门狗与窗口看门狗区别如下:

(1)独立看门狗没有中断,窗口看门狗有中断。

(2)独立看门狗有硬件、软件之分,窗口看门狗只能软件控制。

(3)独立看门狗只有下限,窗口看门狗又下限和上限。

(4)独立看门狗是12位递减的。窗口看门狗是7位递减的。

(5)独立看门狗是用的内部的大约40kHz RC振荡器,窗口看门狗是用的系统时钟APB1ENR。

(6)独立看门狗Iwdg——独立于系统之外,因为有独立时钟,所以不受系统影响的系统故障探测器。

窗口看门狗wwdg——系统内部的故障探测器,时钟与系统相同。如果系统时钟不走了,这个狗也就失去作用了。主要用于监视软件错误。

(7)独立看门狗没有中断功能,窗口看门狗有中断。

        独立看门狗(Independent Watchdog):适用于需要在预定时间间隔内检测系统运行状态的场景。它独立于系统其他组件工作,定期检查系统的活动状态。如果系统在设定的时间内未喂狗,独立看门狗将触发重启操作。用于检测系统死锁、无限循环等严重故障,并执行相应的恢复措施,确保系统稳定性和可靠性。

        窗口看门狗(Windowed Watchdog):适用于需要在严格的时间窗口内监测系统运行状态的场景。它要求系统在指定的时间窗口内喂狗,而不仅仅是在预定时间间隔内。只有在窗口内喂狗,才能防止看门狗触发重启操作。用于实时系统或对时间敏感的应用,确保系统在严格的时间要求内正常运行,避免因执行时间超出预期而触发看门狗重启。

        综合来说,当系统对时间要求较为严格,需要确保在严格的时间窗口内完成特定任务时,通常会选择窗口看门狗。而当需要独立于系统其他组件工作、定期检查系统状态,并在发生严重故障时执行恢复操作时,通常会选择独立看门狗。


http://www.kler.cn/a/308578.html

相关文章:

  • 从华为到创业公司
  • 设计模式之责任链模式(Chain Of Responsibility)
  • GxtWaitCursor:Qt下基于RAII的鼠标等待光标类
  • 基于迭代重加权最小二乘法的算法及例程
  • Xcode 16 使用 pod 命令报错解决方案
  • Linux探秘坊-------1.系统核心的低语:基础指令的奥秘解析(1)
  • new/delete和malloc/free到底有什么区别
  • docker镜像结构
  • 代码随想录:动态规划4-5
  • Java技术深度探索:高并发场景下的线程安全与性能优化
  • java面试题-Sql 语句的执行顺序
  • 【SOP】使用MMDeploy将MMAction2的模型转换为TensorRT
  • 二叉树的前中后序遍历(递归法)( 含leetcode上三道【前中后序】遍历题目)
  • java-lambda-常用方法总结汇总
  • 【乐企】旅客运输发票接口实现
  • 第159天:安全开发-Python-协议库爆破FTPSSHRedisSMTPMYSQL等
  • 持续集成与持续交付CI/CD
  • TDengine 首席架构师肖波演讲整理:探索新型电力系统的五大关键场景与挑战
  • CentOS7下安装Ruby3.2.4的实施路径
  • LeetCode_sql_day26(184,1549,1532,1831)
  • ubuntu系统服务器离线安装python包
  • 力扣(leetcode)每日一题 2848 与车相交的点
  • 7天速成前端 ------学习日志 (继苍穹外卖之后)
  • Spire.PDF for .NET【页面设置】演示:为 PDF 添加背景颜色或背景图像
  • python压缩图片的代码
  • 《锐捷AP 胖模式配置示例》