【STM32】WWDG—窗口看门狗

在一个设定好的区间进行喂狗

与独立看门狗不同的是,独立看门狗只需要在计时到0之前喂狗。而窗口看门狗需要在设定好的区间内进行喂狗,否则进行reset。

下限

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

上限

是窗口看门狗的计数器的值在减到某一个数之前喂狗的话也会产生复位,这个值叫窗口的上限,上限值由用户独立设置。

窗口看门狗计数器的值必须在上窗口和下窗口之间才可以喂狗

功能框图

时钟源

PCLK1,PCLK1 最大是 36M,由 RCC 时钟控制器开启。

计数器时钟 PCLK -> CK时钟 -> 计数器时钟

1.计数器时钟由 CK计时器时钟经过预分频器分频得到。

2.CK 计时器时钟=PCLK1/4096,除以 4096是手册规定的,没有为什么。

3.分频系数由配置寄存器 CFR 的位 8:7 WDGTB[1:0]配置,可以是[0,1,2,3]。

所以计数器的时钟 CNT_CK=PCLK1/4096/(2^WDGTB),这就可以算出计数器减一个数的时间 T= 1/CNT_CK = Tpclk1 * 4096 * (2^WDGTB)。

计数器

1.窗口看门狗的计数器是一个递减计数器,共有 7 位,其值存在控制寄存器 CR 的位 6:0,即 T[6:0]。

2.但是由于窗口看门狗需要在窗口内喂狗,所以计数器的值只能是:0X40~0X7F 之间。

3.当递减计数器递减到 0X40的时候,还不会马上产生复位,如果使能了提前唤醒中断:CFR位 9 EWI 置1,则产生提前唤醒中断

中断服务程序里面我们就需要做最重要的工作,比如保存重要数据,或者报警等

窗口值设置和计算看门狗复位时间

详见参考手册

使用

看门狗配置

c 复制代码
/* WWDG 配置函数
* tr :递减计时器的值, 取值范围为:0x7f~0x40
* wr :窗口值,取值范围为:0x7f~0x40
* prv:预分频器值,取值可以是
* @arg WWDG_Prescaler_1: WWDG counter clock = (PCLK1/4096)/1
* @arg WWDG_Prescaler_2: WWDG counter clock = (PCLK1/4096)/2
* @arg WWDG_Prescaler_4: WWDG counter clock = (PCLK1/4096)/4
* @arg WWDG_Prescaler_8: WWDG counter clock = (PCLK1/4096)/8
*/
 void WWDG_Config(uint8_t tr, uint8_t wr, uint32_t prv)
 {
 // 开启 WWDG 时钟
 RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, ENABLE);
 
 // 设置递减计数器的值
 WWDG_SetCounter( tr );
 
 // 设置预分频器的值
 WWDG_SetPrescaler( prv );
 
 // 设置上窗口值
 WWDG_SetWindowValue( wr );
 
 // 设置计数器的值,使能 WWDG
 WWDG_Enable(WWDG_CNT);
 
 // 清除提前唤醒中断标志位
 WWDG_ClearFlag();
 // 配置 WWDG 中断优先级
 WWDG_NVIC_Config();
 // 开 WWDG 中断
 WWDG_EnableIT();
 }

中断NVIC 配置

c 复制代码
// WWDG 中断优先级初始化
static void WWDG_NVIC_Config(void)
{
NVIC_InitTypeDef NVIC_InitStructure;

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
NVIC_InitStructure.NVIC_IRQChannel = WWDG_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
 }

提前唤醒中断复位程序

这个中断函数的名称就是"提前唤醒中断"

c 复制代码
// WWDG 中断复服务程序,如果发生了此中断,表示程序已经出现了故障,
// 这是一个死前中断。在此中断服务程序中应该干最重要的事,
// 比如保存重要的数据等,这个时间具体有多长,要
// 由 WDGTB 的值决定:
// WDGTB:0 113us
// WDGTB:1 227us
// WDGTB:2 455us
// WDGTB:3 910us
void WWDG_IRQHandler(void)
 {
 // 清除中断标志位
 WWDG_ClearFlag();
  //真正使用的时候,这里应该是做最重要的事情
 }

喂狗函数

c 复制代码
 // 喂狗
 void WWDG_Feed(void)
 {
 // 喂狗,刷新递减计数器的值,设置成最大 WDG_CNT=0X7F
 WWDG_SetCounter( WWDG_CNT );
 }

使用范例

c 复制代码
int main(void)
{
uint8_t wwdg_tr, wwdg_wr;
SOFT_Delay(0X00FFFFFF);
  // 初始化 WWDG
  // 窗口值我们在初始化的时候设置成 0X5F,这个值不会改变
 WWDG_Config(0X7F, 0X5F, WWDG_Prescaler_8);
 
 wwdg_wr = WWDG->CFR & 0X7F;
  while (1) {

 //-----------------------------------------------------
 // 这部分应该写需要被 WWDG 监控的程序,这段程序运行的时间
 // 决定了窗口值应该设置成多大。
 //-----------------------------------------------------
 
 // 计时器值,初始化成最大 0X7F,当开启 WWDG 时候,这个值会不断减小
 // 当计数器的值大于窗口值时喂狗的话,会复位,当计数器减少到 0X40
 // 还没有喂狗的话就非常非常危险了,计数器再减一次到了 0X3F 时就复位
 // 所以要当计数器的值在窗口值和 0X40 之间的时候喂狗,其中 0X40 是固定的。
 wwdg_tr = WWDG->CR & 0X7F;
 
 if ( wwdg_tr < wwdg_wr ) {
 // 喂狗,重新设置计数器的值为最大 0X7F
 WWDG_Feed();
 }
 }
 }
相关推荐
IT阳晨。1 小时前
【STM32】智能台灯项目
stm32·单片机·嵌入式硬件
炸膛坦客2 小时前
Cortex-M3-STM32F1 开发:(三十九)DMA详细介绍(3):相关寄存器、库函数介绍,配置步骤,以及内存到内存和内存到外设的实例
stm32·单片机·嵌入式硬件
BMS小旭3 小时前
CubeMx-GPIO学习
单片机·学习
清风6666665 小时前
基于单片机的PID调节脉动真空灭菌器上位机远程监控设计
数据库·单片机·毕业设计·nosql·课程设计·期末大作业
polarislove02146 小时前
9.6 [定时器]超声波测距实验-嵌入式铁头山羊STM32笔记
笔记·stm32·嵌入式硬件
一路往蓝-Anbo7 小时前
C语言从句柄到对象 (六) —— 继承与 HAL:父类指针访问子类数据
c语言·开发语言·stm32·嵌入式硬件·物联网
一路往蓝-Anbo10 小时前
C语言从句柄到对象 (七) —— 给对象加把锁:RTOS 环境下的并发安全
java·c语言·开发语言·stm32·单片机·嵌入式硬件·算法
一路往蓝-Anbo10 小时前
C语言从句柄到对象 (八) —— 当对象会说话:观察者模式与事件链表
c语言·开发语言·数据结构·stm32·单片机·观察者模式·链表
polarislove021410 小时前
9.5 [定时器]输入捕获-嵌入式铁头山羊STM32笔记
笔记·stm32·嵌入式硬件
国科安芯10 小时前
核工业检测系统通信链路的国产化元器件安全等级评估
运维·网络·人工智能·单片机·嵌入式硬件·安全·安全性测试