目录
1、窗口看门狗概述
2、常用寄存器和库函数配置
3、窗口看门狗实验
1、窗口看门狗概述
之所以称为窗口就是因为其喂狗时间是一个有上下限的范围内(窗口),你可以通过设定相关寄存器,设定其上限时间(下限固定)。喂狗的时间不能过早也不能过晚。
而独立看门狗限制喂狗时间在0-x内,x由相关寄存器决定。喂狗的时间不能过晚。
窗口看门狗工作示意图:
窗口看门狗工作过程总结:
STM32F的窗口看门狗中有一个7位的递减计数器T[6:0],它会在出现下述2种情况之一时产生看门狗复位:
- 当喂狗的时候如果计数器的值大于某一设定数值W[6:0]时,此设定数值在WWDG_CFG寄存器定义。
- 当计数器的数值从0x40减到0x3F时[T6位跳变到0]。
如果启动了看门狗并且允许中断,当递减计数器等于0x40时产生早期唤醒中断(EWI),它可以用于喂狗以避免WWDG复位。
为什么要窗口看门狗:
对于一般的看门狗,程序可以在它产生复位前的任意时刻刷新看门狗,但这有一个隐患,有可能程序跑乱了又跑回到正常的地方,或跑乱的程序正好执行到了刷新看门狗操作,这样的情况下一般的看门狗就检测不出来了。
如果使用窗口看门狗,程序员可以根据程序正常执行的时间设置刷新看门狗的一个时间窗口,保证不会提前刷新看门狗也不会滞后刷新看门狗,这样可以检测出程序没有按照正常的路径运行非正常地跳过了某些程序段的情况。
窗口看门狗其他注意事项:
- 上窗口值W[6:0]必须大于下窗口0x40.否则就无窗口了。
- 窗口看门狗时钟来源PCLK1(APB1总线时钟)分频后。
2、常用寄存器和库函数配置
- 控制寄存器WWDG_CR
- 配置寄存器WWDG_CFR
- 状态寄存器WWDG_SR
窗口看门狗配置过程:
- 使能看门狗时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG,ENABLE); //使能窗口看门狗时钟
- 设置分频系数
WWDG_SetPrescaler(fprer); //设置分频值
- 设置上窗口值
WWDG_SetWindowValue(wr); //设置窗口值
- 开启提前唤醒中断并分组(可选)
WWDG_EnableIT();//开启提前唤醒中断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_Enable(WWDG_CNT); //开启看门狗
- 喂狗
WWDG_SetCounter(WWDG_CNT); //重设窗口看门狗值
- 编写中断服务函数
//窗口看门狗中断服务程序 void WWDG_IRQHandler(void) {WWDG_SetCounter(WWDG_CNT); //重设窗口看门狗值WWDG_ClearFlag();//清除提前唤醒中断标志位LED1=!LED1; }
3、窗口看门狗实验
main.c
#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "beep.h"
#include "key.h"
#include "wwdg.h"//ALIENTEK 探索者STM32F407开发板 实验7
//窗口看门狗实验 -库函数版本
//技术支持:www.openedv.com
//淘宝店铺:http://eboard.taobao.com
//广州市星翼电子科技有限公司
//作者:正点原子 @ALIENTEK int main(void)
{ NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2delay_init(168); //初始化延时函数LED_Init(); //初始化LED端口KEY_Init(); //初始化按键LED0=0; //点亮LED0delay_ms(300);WWDG_Init(0x7F,0X5F,WWDG_Prescaler_8); //计数器值为7f,窗口寄存器为5f,分频数为8 while(1){LED0=1; //熄灭LED灯}
}
wwdg.c
#include "wwdg.h"
#include "led.h"
//
//本程序只供学习使用,未经作者许可,不得用于其它任何用途
//ALIENTEK STM32F407开发板
//看门狗 驱动代码
//正点原子@ALIENTEK
//技术论坛:www.openedv.com
//创建日期:2014/6/12
//版本:V1.0
//版权所有,盗版必究。
//Copyright(C) 广州市星翼电子科技有限公司 2014-2024
//All rights reserved
//********************************************************************************
//V1.1 20140504
//增加了窗口看门狗相关函数。
// //保存WWDG计数器的设置值,默认为最大.
u8 WWDG_CNT=0X7F;
//初始化窗口看门狗
//tr :T[6:0],计数器值
//wr :W[6:0],窗口值
//fprer:分频系数(WDGTB),仅最低2位有效
//Fwwdg=PCLK1/(4096*2^fprer). 一般PCLK1=42Mhz
void WWDG_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; //抢占优先级为2NVIC_InitStructure.NVIC_IRQChannelSubPriority=0x03; //子优先级为3NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE; //使能窗口看门狗NVIC_Init(&NVIC_InitStructure);WWDG_ClearFlag();//清除提前唤醒中断标志位WWDG_EnableIT();//开启提前唤醒中断
}//窗口看门狗中断服务程序
void WWDG_IRQHandler(void)
{WWDG_SetCounter(WWDG_CNT); //重设窗口看门狗值WWDG_ClearFlag();//清除提前唤醒中断标志位LED1=!LED1;
}
效果视频:
7、窗口看门狗实验