STM32
登录
直播中
徐胤
8年用户
1144经验值
私信
关注
[问答]
有关窗口看门狗WWDG的基本知识
开启该帖子的消息推送
WWDG
计数器
怎样去计算窗口看门狗WWDG的超时时间?
窗口看门狗WWDG有哪些应用?
回帖
(1)
邝计嘉
2021-9-27 14:23:36
一.窗口看门狗
窗口看门狗(WWDG)通常被用来监测由外部干扰或不可预见的逻辑条件造成的应用程序背离正常的运行序列而产生的软件故障。除非递减计数器的值在T6位(WWDG-》CR的第六位)变成0前被刷新,看门狗电路在达到预置的时间周期时,会产生一个MCU复位。在递减计数器达到窗口配置寄存器(WWDG-》CFR)数值之前,如果7位的递减计数器数值(在控制寄存器中)被刷新, 那么也将产生一个MCU复位。这表明递减计数器需要在一个有限的时间窗口中被刷新。如图:
T[6:0]就是WWDG_CR的低七位,W[6:0]即是WWDG-》CFR的低七位。T[6:0]
就是窗口看门狗的计数器,而W[6:0]则是窗口看门狗的上窗口,下窗口值是固定的(0X40)。当窗口看门狗的计数器在上窗口值之外被刷新,或者低于下窗口值都会产生复位。上窗口值(W[6:0])是由用户自己设定的,根据实际要求来设计窗口值,但是一定要确保窗口值大于0X40,否则窗口就不存在了。
窗口看门狗的超时公式如下:
Twwdg=(4096×2^WDGTB×(T[5:0]+1))/Fpclk1;
其中:
Twwdg:WWDG超时时间(单位为ms)
Fpclk1:APB1的时钟频率(单位为Khz)
WDGTB:WWDG的预分频系数
T[5:0]:窗口看门狗的计数器低6位
根据上面的公式,假设Fpclk1=42Mhz,那么可以得到最小-最大超时时间表如图所示:
接下来,我们介绍窗口看门狗的3个寄存器。首先介绍控制寄存器(WWDG_CR),该 寄存器的各位描述如图
可以看出,这里我们的WWDG_CR只有低八位有效,T[6:0]用来存储看门狗的计数器值,随时更新的,每个窗口看门狗计数周期(4096×2^WDGTB)减1。当该计数器的值从0X40变为0X3F的时候,将产生看门狗复位。WDGA位则是看门狗的激活位,该位由软件置1,以启动看门狗,并且一定要注意的是该位一旦设置,就只能在硬件复位后才能清零了。
窗口看门狗的第二个寄存器是配置寄存器(WWDG_CFR),该寄存器的各位及其描述如图
该位中的EWI是提前唤醒中断,也就是在快要产生复位的前一段时间(T[6:0]=0X40)来提醒我们,需要进行喂狗了,否则将复位!因此,我们一般用该位来设置中断,当窗口看门狗的计数器值减到0X40的时候,如果该位设置,并开启了中断,则会产生中断,我们可以在中断里面向WWDG_CR重新写入计数器的值,来达到喂狗的目的。注意这里在进入中断后,必须在不大于1个窗口看门狗计数周期的 时 间(在PCLK1频率为42M且WDGTB为0的条件下,该时间为97.52us)内重新写WWDG_CR,否则,看门狗将产生复位!
最后我们要介绍的是状态寄存器(WWDG_SR),该寄存器用来记录当前是否有提前唤醒的标志。该寄存器仅有位0有效,其他都是保留位。当计数器值达到40h时,此位由硬件置1。它必须通过软件写0来清除。对此位写1无效。即使中断未被使能,在计数器的值达到0X40的时候,此位也会被置1,窗口看门狗库函数相关源码和定义分布在文件stm32f4xx_wwdg.c文件和头文件stm32f4xx_wwdg.h中
二.窗口看门狗应用
1)使能WWDG时钟
WWDG不同于IWDG,IWDG 有自己独立的32Khz时钟,不存在使能问题。而WWDG使用的是PCLK1的时钟,需要先使能时钟。方法是:
RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, ENABLE); //WWDG时钟使能
2)设置窗口值和分频数
设置窗口值的函数是:
voidWWDG_SetWindowValue(uint8_t WindowValue);
这个函数就一个入口参数为窗口值,很容易理解。设置分频数的函数是:
voidWWDG_SetPrescaler(uint32_t WWDG_Prescaler);
这个函数同样只有一个入口参数就是分频值。
3)开启WWDG中断并分组
开启WWDG中断的函数为:
WWDG_EnableIT();//开启窗口看门狗中断
接下来是进行中断优先级配置,这里就不重复了,使用NVIC_Init()函数即可。
4)设置计数器初始值并使能看门狗
这一步在库函数里面是通过一个函数实现的:
voidWWDG_Enable(uint8_t Counter);
该函数既设置了计数器初始值,同时使能了窗口看门狗。
这里还需要说明一下,库函数还提供了一个独立的设置计数器值的函数为:
voidWWDG_SetCounter(uint8_t Counter);
5)编写中断服务函数
在最后,还是要编写窗口看门狗的中断服务函数,通过该函数来喂狗,喂狗要快,否则当窗口看门狗计数器值减到0X3F的时候,就会引起软复位了。在中断服务函数里面也要将状态寄存器的EWIF位清空。
三.窗口看门狗源码
Wwdog.h
#ifndef_WWDOG_H_H_H
#define_WWDOG_H_H_H
#include“stm32f4xx_wwdg.h”
voidWWDG_Init(u8 tr,u8 wr,u32 fprer);
voidWWDG_IRQHandler(void);
#endif
Wwdog.c
#include“wwdog.h”
#include“led.h”
//保存WWDG计数器的设置值,默认为最大。
u8WWDG_CNT=0X7F;
voidWWDG_Init(u8 tr,u8 wr,u32 fprer)
{
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG,ENABLE); //使能窗口看门狗时钟
WWDG_CNT=tr&WWDG_CNT; //初始化WWDG_CNT.
WWDG_SetPrescaler(fprer); //设置分频值
WWDG_SetWindowValue(wr); //设置窗口值
//WWDG_SetCounter(WWDG_CNT);//设置计数值
WWDG_Enable(WWDG_CNT); //开启看门狗
NVIC_InitStructure.NVIC_IRQChannel=WWDG_IRQn; //窗口看门狗中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0x02; //抢占优先级为2
NVIC_InitStructure.NVIC_IRQChannelSubPriority=0x03; //子优先级为3
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE; //使能窗口看门狗
NVIC_Init(&NVIC_InitStructure);
WWDG_ClearFlag();//清除提前唤醒中断标志位
WWDG_EnableIT();//开启提前唤醒中断
}
//窗口看门狗中断服务程序
voidWWDG_IRQHandler(void)
{
static int count = 0;
WWDG_SetCounter(WWDG_CNT); //重设窗口看门狗值
WWDG_ClearFlag();//清除提前唤醒中断标志位
if(count++ % 2 == 0)
{
LED_Operate(LED_RED,LED_ON);
}
else
{
LED_Operate(LED_RED,LED_OFF);
}
}
Main.c
#include“led.h”
#include“key.h”
#include“delay.h”
#include“uart.h”
#include“exit.h”
#include“iwdog.h”
voidUser_Delay(__IO uint32_t nCount)
{
while(nCount--)
{
}
}
staticint count = 0;
intmain(void)
{
#if 1
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2
delay_init(168); //初始化延时函数
LED_Init(); //初始化LED端口
KEY_Init(); //初始化按键
LED_Operate(LED_BLUE,LED_ON); //点亮LED0
delay_ms(300);
WWDG_Init(0x7F,0X5F,WWDG_Prescaler_8); //计数器值为7f,窗口寄存器为5f,分频数为8
while(1)
{
LED_Operate(LED_BLUE,LED_OFF);
}
#endif
}
一.窗口看门狗
窗口看门狗(WWDG)通常被用来监测由外部干扰或不可预见的逻辑条件造成的应用程序背离正常的运行序列而产生的软件故障。除非递减计数器的值在T6位(WWDG-》CR的第六位)变成0前被刷新,看门狗电路在达到预置的时间周期时,会产生一个MCU复位。在递减计数器达到窗口配置寄存器(WWDG-》CFR)数值之前,如果7位的递减计数器数值(在控制寄存器中)被刷新, 那么也将产生一个MCU复位。这表明递减计数器需要在一个有限的时间窗口中被刷新。如图:
T[6:0]就是WWDG_CR的低七位,W[6:0]即是WWDG-》CFR的低七位。T[6:0]
就是窗口看门狗的计数器,而W[6:0]则是窗口看门狗的上窗口,下窗口值是固定的(0X40)。当窗口看门狗的计数器在上窗口值之外被刷新,或者低于下窗口值都会产生复位。上窗口值(W[6:0])是由用户自己设定的,根据实际要求来设计窗口值,但是一定要确保窗口值大于0X40,否则窗口就不存在了。
窗口看门狗的超时公式如下:
Twwdg=(4096×2^WDGTB×(T[5:0]+1))/Fpclk1;
其中:
Twwdg:WWDG超时时间(单位为ms)
Fpclk1:APB1的时钟频率(单位为Khz)
WDGTB:WWDG的预分频系数
T[5:0]:窗口看门狗的计数器低6位
根据上面的公式,假设Fpclk1=42Mhz,那么可以得到最小-最大超时时间表如图所示:
接下来,我们介绍窗口看门狗的3个寄存器。首先介绍控制寄存器(WWDG_CR),该 寄存器的各位描述如图
可以看出,这里我们的WWDG_CR只有低八位有效,T[6:0]用来存储看门狗的计数器值,随时更新的,每个窗口看门狗计数周期(4096×2^WDGTB)减1。当该计数器的值从0X40变为0X3F的时候,将产生看门狗复位。WDGA位则是看门狗的激活位,该位由软件置1,以启动看门狗,并且一定要注意的是该位一旦设置,就只能在硬件复位后才能清零了。
窗口看门狗的第二个寄存器是配置寄存器(WWDG_CFR),该寄存器的各位及其描述如图
该位中的EWI是提前唤醒中断,也就是在快要产生复位的前一段时间(T[6:0]=0X40)来提醒我们,需要进行喂狗了,否则将复位!因此,我们一般用该位来设置中断,当窗口看门狗的计数器值减到0X40的时候,如果该位设置,并开启了中断,则会产生中断,我们可以在中断里面向WWDG_CR重新写入计数器的值,来达到喂狗的目的。注意这里在进入中断后,必须在不大于1个窗口看门狗计数周期的 时 间(在PCLK1频率为42M且WDGTB为0的条件下,该时间为97.52us)内重新写WWDG_CR,否则,看门狗将产生复位!
最后我们要介绍的是状态寄存器(WWDG_SR),该寄存器用来记录当前是否有提前唤醒的标志。该寄存器仅有位0有效,其他都是保留位。当计数器值达到40h时,此位由硬件置1。它必须通过软件写0来清除。对此位写1无效。即使中断未被使能,在计数器的值达到0X40的时候,此位也会被置1,窗口看门狗库函数相关源码和定义分布在文件stm32f4xx_wwdg.c文件和头文件stm32f4xx_wwdg.h中
二.窗口看门狗应用
1)使能WWDG时钟
WWDG不同于IWDG,IWDG 有自己独立的32Khz时钟,不存在使能问题。而WWDG使用的是PCLK1的时钟,需要先使能时钟。方法是:
RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, ENABLE); //WWDG时钟使能
2)设置窗口值和分频数
设置窗口值的函数是:
voidWWDG_SetWindowValue(uint8_t WindowValue);
这个函数就一个入口参数为窗口值,很容易理解。设置分频数的函数是:
voidWWDG_SetPrescaler(uint32_t WWDG_Prescaler);
这个函数同样只有一个入口参数就是分频值。
3)开启WWDG中断并分组
开启WWDG中断的函数为:
WWDG_EnableIT();//开启窗口看门狗中断
接下来是进行中断优先级配置,这里就不重复了,使用NVIC_Init()函数即可。
4)设置计数器初始值并使能看门狗
这一步在库函数里面是通过一个函数实现的:
voidWWDG_Enable(uint8_t Counter);
该函数既设置了计数器初始值,同时使能了窗口看门狗。
这里还需要说明一下,库函数还提供了一个独立的设置计数器值的函数为:
voidWWDG_SetCounter(uint8_t Counter);
5)编写中断服务函数
在最后,还是要编写窗口看门狗的中断服务函数,通过该函数来喂狗,喂狗要快,否则当窗口看门狗计数器值减到0X3F的时候,就会引起软复位了。在中断服务函数里面也要将状态寄存器的EWIF位清空。
三.窗口看门狗源码
Wwdog.h
#ifndef_WWDOG_H_H_H
#define_WWDOG_H_H_H
#include“stm32f4xx_wwdg.h”
voidWWDG_Init(u8 tr,u8 wr,u32 fprer);
voidWWDG_IRQHandler(void);
#endif
Wwdog.c
#include“wwdog.h”
#include“led.h”
//保存WWDG计数器的设置值,默认为最大。
u8WWDG_CNT=0X7F;
voidWWDG_Init(u8 tr,u8 wr,u32 fprer)
{
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG,ENABLE); //使能窗口看门狗时钟
WWDG_CNT=tr&WWDG_CNT; //初始化WWDG_CNT.
WWDG_SetPrescaler(fprer); //设置分频值
WWDG_SetWindowValue(wr); //设置窗口值
//WWDG_SetCounter(WWDG_CNT);//设置计数值
WWDG_Enable(WWDG_CNT); //开启看门狗
NVIC_InitStructure.NVIC_IRQChannel=WWDG_IRQn; //窗口看门狗中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0x02; //抢占优先级为2
NVIC_InitStructure.NVIC_IRQChannelSubPriority=0x03; //子优先级为3
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE; //使能窗口看门狗
NVIC_Init(&NVIC_InitStructure);
WWDG_ClearFlag();//清除提前唤醒中断标志位
WWDG_EnableIT();//开启提前唤醒中断
}
//窗口看门狗中断服务程序
voidWWDG_IRQHandler(void)
{
static int count = 0;
WWDG_SetCounter(WWDG_CNT); //重设窗口看门狗值
WWDG_ClearFlag();//清除提前唤醒中断标志位
if(count++ % 2 == 0)
{
LED_Operate(LED_RED,LED_ON);
}
else
{
LED_Operate(LED_RED,LED_OFF);
}
}
Main.c
#include“led.h”
#include“key.h”
#include“delay.h”
#include“uart.h”
#include“exit.h”
#include“iwdog.h”
voidUser_Delay(__IO uint32_t nCount)
{
while(nCount--)
{
}
}
staticint count = 0;
intmain(void)
{
#if 1
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2
delay_init(168); //初始化延时函数
LED_Init(); //初始化LED端口
KEY_Init(); //初始化按键
LED_Operate(LED_BLUE,LED_ON); //点亮LED0
delay_ms(300);
WWDG_Init(0x7F,0X5F,WWDG_Prescaler_8); //计数器值为7f,窗口寄存器为5f,分频数为8
while(1)
{
LED_Operate(LED_BLUE,LED_OFF);
}
#endif
}
举报
更多回帖
rotate(-90deg);
回复
相关问答
WWDG
计数器
有关窗口
看门狗
(
WWDG
)的
基本知识
汇总
2021-08-09
2033
IWDG独立
看门狗
与
WWDG
窗口
看门狗
开发指南
2021-09-23
1468
有关窗口
看门狗
WWDG
的相关
知识
简析
2021-09-23
1275
有关窗口
看门狗
的
基本知识
汇总
2021-09-09
1920
如何防止
窗口
看门狗
(
WWDG
)复位
2021-08-12
2155
独立
看门狗
IWDG与
窗口
看门狗
WWDG
的区别在哪
2021-09-26
1571
窗口
看门狗
(
WWDG
)库函数配置有哪些步骤
2021-08-16
1739
窗口
看门狗
WWDG
比独立
看门狗
IWDG多了哪些优势
2021-09-23
1322
窗口
看门狗
WWDG
该怎样去使用呢
2022-01-17
1289
窗口
看门狗
(
WWDG
)与独立
看门狗
(IWDG)有何区别?
2021-07-22
2360
发帖
登录/注册
20万+
工程师都在用,
免费
PCB检查工具
无需安装、支持浏览器和手机在线查看、实时共享
查看
点击登录
登录更多精彩功能!
首页
论坛版块
小组
免费开发板试用
ebook
直播
搜索
登录
×
20
完善资料,
赚取积分