窗口看门狗 WWDG
一,窗口看门狗

二,喂狗注意事项

三,程序设计
1.检查复位状态,有助于观察当前工作的可靠性
/* Check if the system has resumed from WWDG reset ,检查是否窗口看门狗导致的复位,如果发现由窗口看门狗导致的复位,输出打印信息*/
if (RCC_GetFlagStatus(RCC_FLAG_WWDGRST) != RESET)
{
/* WWDGRST flag set */
printf("wwdg reset cpu\r\n"); /* Clear reset flags */
RCC_ClearFlag();
}
else
{
/* WWDGRST flag is not set */
printf("normal reset cpu\r\n");
} delay_ms();delay_ms();
2. 看门狗的初始化
/* WWDG configuration ,窗口看门狗的配置*/
/* Enable WWDG clock ,使能看门狗的时钟*/
RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, ENABLE); /* 窗口看门狗的时钟 = (PCLK1 (42MHz)/4096)/8 = 1281 Hz (~780 us) */
WWDG_SetPrescaler(WWDG_Prescaler_8); /* Set Window value to 80; WWDG counter should be refreshed only when the counter
is below 80 (and greater than 0x40) otherwise a reset will be generated
设置窗口的上限值为80
*/
WWDG_SetWindowValue(); /* 设置计数值的初值为127,则窗口看门狗的超时时间 = 780 us * 64 = 49.92 ms
这个时候窗口刷新时间如下
~780 * (127-80) = 36.6ms < refresh window < ~780 * 64 = 49.9ms */
WWDG_Enable(); //WWDG NVIC 配置
NVIC_InitStructure.NVIC_IRQChannel = WWDG_IRQn; //窗口看门狗中断通道
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=; //抢占优先级0
NVIC_InitStructure.NVIC_IRQChannelSubPriority =; //子优先级0
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能
NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器 //清空提前唤醒中断标志位
WWDG_ClearFlag(); //使能提前唤醒中断
WWDG_EnableIT();

3. 看门狗中断服务函数
void WWDG_IRQHandler(void)
{
if(WWDG_GetFlagStatus()==SET)
{
//进行喂狗
WWDG_SetCounter(); //清空提前唤醒中断标志位
WWDG_ClearFlag(); }
}
#include "stm32f4xx.h"
#include "stm32f4xx_gpio.h"
#include "stm32f4xx_rcc.h"
#include "stm32f4xx_usart.h"
#include "stdio.h"
#include "sys.h" static GPIO_InitTypeDef GPIO_InitStructure;
static USART_InitTypeDef USART_InitStructure;
static NVIC_InitTypeDef NVIC_InitStructure; //重定义fputc函数
int fputc(int ch, FILE *f)
{
USART_SendData(USART1,ch);
while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET); return ch;
} void delay_us(uint32_t nus)
{
uint32_t temp;
SysTick->LOAD =SystemCoreClock//*nus; //时间加载
SysTick->VAL =0x00; //清空计数器
SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ; //使能滴答定时器开始倒数
do
{
temp=SysTick->CTRL;
}while((temp&0x01)&&!(temp&(<<))); //等待时间到达
SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk; //关闭计数器
SysTick->VAL =0X00; //清空计数器
} void delay_ms(uint16_t nms)
{
uint32_t temp;
SysTick->LOAD=SystemCoreClock//*nms; //时间加载(SysTick->LOAD为24bit)
SysTick->VAL =0x00; //清空计数器
SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ; //能滴答定时器开始倒数
do
{
temp=SysTick->CTRL;
}while((temp&0x01)&&!(temp&(<<))); //等待时间到达
SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk; //关闭计数器
SysTick->VAL =0X00; //清空计数器
} void LED_Init(void)
{ //使能GPIOE,GPIOF时钟
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE | RCC_AHB1Periph_GPIOF, ENABLE); //GPIOF9,F10初始化设置
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10; //LED0和LED1对应IO口
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; //普通输出模式,
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽输出,驱动LED需要电流驱动
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; //100MHz
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //上拉
GPIO_Init(GPIOF, &GPIO_InitStructure); //初始化GPIOF,把配置的数据写入寄存器 //GPIOE13,PE14初始化设置
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14; //LED2和LED3对应IO口
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; //普通输出模式
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; //100MHz
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //上拉
GPIO_Init(GPIOE, &GPIO_InitStructure); //初始化GPIOE,把配置的数据写入寄存器 GPIO_SetBits(GPIOF,GPIO_Pin_9 | GPIO_Pin_10); //GPIOF9,PF10设置高,灯灭
GPIO_SetBits(GPIOE,GPIO_Pin_13 | GPIO_Pin_14);
} void USART1_Init(uint32_t baud)
{
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE); //使能GPIOA时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE); //使能USART1时钟 //串口1对应引脚复用映射
GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,GPIO_AF_USART1); //GPIOA9复用为USART1
GPIO_PinAFConfig(GPIOA,GPIO_PinSource10,GPIO_AF_USART1); //GPIOA10复用为USART1 //USART1端口配置
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10; //GPIOA9与GPIOA10
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; //复用功能
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //速度50MHz
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽复用输出
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //上拉
GPIO_Init(GPIOA,&GPIO_InitStructure); //初始化PA9,PA10 //USART1 初始化设置
USART_InitStructure.USART_BaudRate = baud; //波特率设置
USART_InitStructure.USART_WordLength = USART_WordLength_8b; //字长为8位数据格式
USART_InitStructure.USART_StopBits = USART_StopBits_1; //一个停止位
USART_InitStructure.USART_Parity = USART_Parity_No; //无奇偶校验位
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; //无硬件数据流控制
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //收发模式
USART_Init(USART1, &USART_InitStructure); //初始化串口1 USART_Cmd(USART1, ENABLE); //使能串口1 USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); //开启相关中断 //Usart1 NVIC 配置
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; //串口1中断通道
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=; //抢占优先级3
NVIC_InitStructure.NVIC_IRQChannelSubPriority =; //子优先级3
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能
NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器
} int main(void)
{ LED_Init(); //系统定时器初始化,时钟源来自HCLK,且进行8分频,
//系统定时器时钟频率=168MHz/8=21MHz
SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8); //设置中断优先级分组2
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //串口1,波特率115200bps,开启接收中断
USART1_Init(); /* Check if the system has resumed from WWDG reset ,检查是否窗口看门狗导致的复位,如果发现由窗口看门狗导致的复位,输出打印信息*/
if (RCC_GetFlagStatus(RCC_FLAG_WWDGRST) != RESET)
{
/* WWDGRST flag set */
printf("wwdg reset cpu\r\n"); /* Clear reset flags */
RCC_ClearFlag();
}
else
{
/* WWDGRST flag is not set */
printf("normal reset cpu\r\n");
} delay_ms();delay_ms(); /* WWDG configuration ,窗口看门狗的配置*/
/* Enable WWDG clock ,使能看门狗的时钟*/
RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, ENABLE); /* 窗口看门狗的时钟 = (PCLK1 (42MHz)/4096)/8 = 1281 Hz (~780 us) */
WWDG_SetPrescaler(WWDG_Prescaler_8); /* Set Window value to 80; WWDG counter should be refreshed only when the counter
is below 80 (and greater than 0x40) otherwise a reset will be generated
设置窗口的上限值为80
*/
WWDG_SetWindowValue(); /* 设置计数值的初值为127,则窗口看门狗的超时时间 = 780 us * 64 = 49.92 ms
这个时候窗口刷新时间如下
~780 * (127-80) = 36.6ms < refresh window < ~780 * 64 = 49.9ms */
WWDG_Enable(); //WWDG NVIC 配置
NVIC_InitStructure.NVIC_IRQChannel = WWDG_IRQn; //窗口看门狗中断通道
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=; //抢占优先级0
NVIC_InitStructure.NVIC_IRQChannelSubPriority =; //子优先级0
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能
NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器 //清空提前唤醒中断标志位
WWDG_ClearFlag(); //使能提前唤醒中断
WWDG_EnableIT(); while()
{
#if 0
//进行喂狗
WWDG_SetCounter(); //清空提前唤醒中断标志位
WWDG_ClearFlag();
#endif }
} void WWDG_IRQHandler(void)
{
if(WWDG_GetFlagStatus()==SET)
{
//进行喂狗
WWDG_SetCounter(); //清空提前唤醒中断标志位
WWDG_ClearFlag(); }
} void USART1_IRQHandler(void) //串口1中断服务程序
{
uint8_t d; if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //接收中断
{ }
}
wwdg.c
窗口看门狗 WWDG的更多相关文章
- stm32 窗口看门狗 WWDG
窗口看门狗WWDG其实和独立看门狗类似,它是一个7位递减计数器不断的往下递减计数,当减到一个固定值0x40时还不喂狗的话,产生一个MCU复位,这个值叫窗口的下限,是固定的值,不能改变 窗口看门狗(WW ...
- STM32之独立看门狗(IWDG)与窗口看门狗(WWDG)总结
一.独立看门狗 STM32 的独立看门狗由内部专门的 40Khz 低速时钟驱动,即使主时钟发生故障,它也仍然有效. 看门狗的原理:单片机系统在外界的干扰下会出现程序跑飞的现象导致出现死循环,看门狗电路 ...
- STM32窗口看门狗WWDG库函数的一点思考
WWDG当前计数器的值以及激活位和WWDG_CR这个寄存器相关.如下图所示: 而STM32f10x的库函数提供了两种设置WWDG_CR[0:6]位的方式. WWDG_SetCounter方法 #def ...
- 嵌入式02 STM32 实验09 独立/窗口看门狗
一.独立看门狗和窗口看门狗 看门狗:单片机系统在外界的干扰下会出现程序跑飞的现象导致死循环,或者崩溃,看门狗电路就是为了避免这种情况的发生,看门狗的作用就是在一定的事件内(通过计数器实现)若没有收到喂 ...
- 第35章 WWDG—窗口看门狗—零死角玩转STM32-F429系列
第35章 WWDG—窗口看门狗 全套200集视频教程和1000页PDF教程请到秉火论坛下载:www.firebbs.cn 野火视频教程优酷观看网址:http://i.youku.com/fir ...
- STM32之独立看门狗与窗口看门狗总结
一.独立看门狗 STM32 的独立看门狗由内部专门的 40Khz 低速时钟驱动,即使主时钟发生故障,它也仍然有效. 看门狗的原理:单片机系统在外界的干扰下会出现程序跑飞的现象导致出现死循环,看门狗电路 ...
- stm8的独立看门狗与窗口看门狗
STM8拥有两个硬件看门狗,分别叫做独立看门狗和窗口看门狗 独立看门狗的框图如下 我们可以看到,独立看门狗的时钟来自于LSI内部低速振荡器,经过二分频到达看门狗外设单元,在经过一个七位的预分频到达计数 ...
- STM32(10)——窗口看门狗
简介: 窗口看门狗(WWDG)通常被用来监测由外部干扰或不可预见的逻辑条件造成的应用程序背离正常的运行序列而产生的软件故障.除非递减计数器的值在 T6 位 (WWDG->CR 的第六位)变成 0 ...
- stm32 窗口看门狗学习(二)
窗口看门狗有一个提前唤醒中断,如果开启这个中断,那么当计数器的值达到0x40的时候就会产生这个中断. 上次的代码加一点就可以做这个实验了. void WWDG_Init(u8 tr,u8 wr,u32 ...
随机推荐
- C# 简单的区块链实现
1.项目配置 首先新建一个 Asp.Net Core 项目,然后选择 Empty Project(空项目) 类型,建立完成后无需进行任何配置. 2.数据模型 这里我们来创建一个具体的区块数据模型,使用 ...
- 整合MyBatis
配置数据源相关属性(见前一章节 DataSource配置) 引入依赖 <dependency> <groupId>org.mybatis.spring.boot</gro ...
- UOJ220 [NOI2016] 网格 【割顶】【并查集】
题目分析: 答案显然只有{-1,0,1,2}四种. 对于答案等于-1的情况,只有两种情况,一种是只剩一只跳蚤,另一种是只剩两只跳蚤且他们四连通,这个很好判. 对于答案等于0的情况,那说明联通块大于1, ...
- windows下使用 fdfs_client 上传文件(转)
https://www.cnblogs.com/kindleheart/p/10134502.html 注意:client = Fdfs_client(r"绝对路径"),一定要是绝 ...
- Spring Cloud Alibaba学习笔记(4) - Feign配置与使用
什么是Feign Feign是一个声明式Web Service客户端. 使用Feign能让编写Web Service客户端更加简单, 它的使用方法是定义一个接口,然后在上面添加注解,同时也支持JAX- ...
- sql server中:isnull(列名,0) 和isnull(列名,0)<>0 的区别
1.isnull(参数1,参数2),判断参数1是否为NULL,如果是,返回参数2,否则返回参数1. 2.isnull(列名,0),isnull()函数是用来判断列名是否为null,如果为NUll,则返 ...
- RabbitMQ消息队列入门(一)——RabbitMQ消息队列的安装(Windows环境下)
一.RabbitMQ介绍1.RabbitMQ简介RabbitMQ是一个消息代理:它接受和转发消息.你可以把它想象成一个邮局:当你把你想要发布的邮件放在邮箱中时,你可以确定邮差先生最终将邮件发送给你的收 ...
- J.U.C之读写锁:ReentrantReadWriteLock
此篇博客所有源码均来自JDK 1.8 重入锁ReentrantLock是排他锁,排他锁在同一时刻仅有一个线程可以进行访问,但是在大多数场景下,大部分时间都是提供读服务,而写服务占有的时间较少.然而读服 ...
- VS2017 CMD多出 “进程 6420)已退出,返回代码为: 0”的内容
执行cmd, 命令行多出如下内容 xxxx\project.exe (进程 6420)已退出,返回代码为: 0. VS 取消设置方式: 工具->选项->调试-->常规 拉到最 ...
- linux IPC简单学习
Posix和system v区别 所谓的IPC(进程间通信)指的是消息队列,共享内存,信号量3种机制合并起来,当然,这是个狭义的概念,只包含这三种.IPC又可以分为system v进程间通信和posi ...