1.1看门狗概述
1.1.1看门狗作用
检测程序异常或者卡死,如程序卡死或者异常则使用看门狗复位,让程序重新开始运行
eg:
看门狗:作用就是复位,重新开始程序,防止程序卡死
看门狗属于定时器的一种-----每到一定的时间就复位一次
判断程序是否正常的运行了----如果程序正常的执行了就不复位,否则就复位
如果想要看门狗不复位------不停的喂狗
1.1.2看门狗分类
在STM32中看门狗分为两种:独立看门狗/窗口看门狗
此器件具有两个嵌入式看门狗外设,具有安全性高、定时准确及使用灵活的优点。两个看门
狗外设(独立和窗口)均可用于检测并解决由软件错误导致的故障;当计数器达到给定的超
时值时,触发一个中断(仅适用于窗口型看门狗)或产生系统复位。
独立看门狗 (IWDG) 由其专用低速时钟 (LSI) 驱动,因此即便在主时钟发生故障时仍然保持
工作状态。窗口看门狗 (WWDG) 时钟由 APB1 时钟经预分频后提供,通过可配置的时间窗
口来检测应用程序非正常的过迟或过早的操作。
IWDG 最适合应用于那些需要看门狗作为一个在主程序之外,能够完全独立工作,并且对时
间精度要求较低的场合。WWDG 最适合那些要求看门狗在精确计时窗口起作用的应用程
序。
独立看门狗 窗口看门狗----都是复位
独立看门狗:到时间复位
窗口看门狗:窗口值范围内不喂狗复位
独立看门狗由内部低速时钟(LSI)直接提供-----和主频不挂钩
窗口看门狗由APB1总线提供频率--- 42Mhz
时钟树补充:LSI(内部低速时钟)、LSE(外部低速时钟)、HSI(内部高速时钟)、HSE(外部高速时钟)
喂狗概念补充:
喂狗------程序每隔一段时间需要喂一次狗(可在定时器更新中断喂狗)----不喂狗就复位
1.2 独立看门狗
1.2.1 STM32独立看门狗简介
独立看门狗 (IWDG) 由其专用低速时钟 (LSI) 驱动,因此即便在主时钟发生故障时仍然保持
工作状态
特性:
● 自由运行递减计数器
● 时钟由独立 RC 振荡器提供(可在待机和停止模式下运行)
● 当递减计数器值达到 0x000 时产生复位(如果看门狗已激活)
总结:独立看门狗本质为一个计数器(定时器),时钟源由RC震荡源提供(LSI),当计数器递减到0时产生复位
1.2.2 独立看门狗框架
由于stm32f4xx.h中文参考手册框图不完整,此处参考英文参考手册作出补充,如下图:
![](https://img-blog.csdnimg.cn/img_convert/8c3e7d15c069591f695623df1bfebbb9.png)
时钟源LSI部分:
独立看门狗的时钟源由LSI内部低速时钟源,其频率不是相对稳定的,经测试LSI的频率范围为30Khz~60Khz,所以喂狗需要在这个范围之前喂
预分频寄存器:设置分频数,载入到预分频器中
状态寄存器:查看看门狗计数器重载值和分频值是否更新
重载寄存器:设置重装载值,加载到12位计数器中
密钥寄存器(关键字寄存器(只写)):这个寄存器作用多分点作答
喂狗作用,在递减到0之前写入键值0xAAAA防止程序复位
写入键值 0x5555 可使能对 IWDG_PR 和 IWDG_RLR 寄存器的访问,需要在设置重装载值和分频值前写入
启动看门狗,写入键值0xCCCC
注意:看门狗只要启动后就无法中途停止
1.2.3 独立看门狗代码环节
所以配置程序的过程非常简单:
往密钥寄存器里写入0x5555,解放重装载值和分频值的设置权限
设置重装载值
设置预分频值
密钥寄存器写入0xAAAA加载重装载值到12位计数器中
密钥寄存器写入0x5555启动独立看门狗
idwg.c:
#include "idwg.h"
void Idwg_Init(void)
{
IWDG->KR = 0x5555;//往密钥寄存器里写入0x5555,解放重装载值和分频值的设置权限
IWDG->PR = 2;//设置预分频值
IWDG->RLR = 1000;//设置重装载值
IWDG->KR = 0xAAAA;//密钥寄存器写入0xAAAA加载重装载值到12位计数器中
IWDG->KR = 0xCCCC;//密钥寄存器写入0x5555启动独立看门狗
}
idwg.h
#ifndef _IDWG_H
#define _IDWG_H
#include "includes.h"
void Idwg_Init(void);
#endif
1.3 窗口看门狗
1.3.1窗口看门狗概述
窗口看门狗与独立看门狗作用一致,都是递减计数器
窗口看门狗与独立看门狗区别:
独立看门狗:在计数值减到0之前喂狗 递减计数器为12bit,取值范围0~4095
窗口看门狗:在一定的范围之间喂狗 递减计数器为7bit,取值范围0~0x7f
不能提前喂狗,也不能太迟喂狗
独立看门狗:内部低速时钟源(LSI) 32Khz左右
窗口看门狗:挂靠在APB1控制总线上的,42Mhz
1.3.2 窗口看门狗特征
窗口看门狗为可编程的自由运行递减计数器
● | 复位条件 |
— — | 当递减计数器值小于 0x40 时复位(如果看门狗已激活) 在窗口之外重载递减计数器时复位(如果看门狗已激活)(请参见图 200) |
● | 提前唤醒中断 (EWI):当递减计数器等于 0x40 时触发(如果已使能且看门狗已激活) |
1.3.3 窗口看门狗喂狗
![](https://img-blog.csdnimg.cn/img_convert/fdc90765f5f1040f25e01c797376ba4b.png)
喂狗时间范围例子:
WWDG:42Mhz WDGTB:3
每隔 (4096 x 2^WDGTB) PCLK1 个周期递减一次
分频之后频率:1Mhz 窗口值:0x6f
递减一次所需要的时间:T = (4096 * 2^3) /42Mhz= 32768 / 42Mhz = 780us
窗口值~0x7f时间:Tearly = (0x7f -0x6f)*T = 16 * 780us = 12.48ms
0x3f ~ 0x7f时间:Tlate = (0x7f - 0x3f)*T = 64 * 780us = 49.92ms
此例子喂狗范围:12.48ms~49.92ms之间
1.3.4 窗口看门狗框图
![](https://img-blog.csdnimg.cn/img_convert/484d6106b7badb6dd38b8b423e7ca037.png)
注意:计数值大于窗口值
1.3.5窗口看门狗代码环节
代码流程:
打开时钟
配置寄存器
设置计数值、窗口值、WDGTB
使能窗口看门狗
wwdg.c:在中断服务函数中喂狗
#include "wwdg.h"
void Wwdg_Init(void)
{
RCC->APB1ENR |= 1 << 11;
WWDG->CR |= 0x7f << 0;
WWDG->CR |= 1 << 7;
WWDG->CFR |= 1 << 9;
WWDG->CFR |= 3 << 7;
WWDG->CFR &=~ (0x7f << 0);
WWDG->CFR |= 0x6f << 0;
//NVIC配置
NVIC_SetPriority(WWDG_IRQn,NVIC_EncodePriority(5,2,2));//设置USART1中断具体占先和次级优先级的级别值
NVIC_EnableIRQ(WWDG_IRQn);//使能USART1中断源
}
void WWDG_IRQHandler(void)
{
WWDG->SR &=~ (1 << 0);
while(WWDG->SR & (1 << 0));
WWDG->CR |= 0x7f << 0;
}
wwdg.h
#ifndef _WWDG_H
#define _WWDG_H
#include "includes.h"
void Wwdg_Init(void);
#endif
main.c
int main()
{
NVIC_SetPriorityGrouping(7-2);//分成第2组,占先位数2位 次级位数2位 占先取值范围:0-3 次级取值范围:0-3
Usart1_Init(115200); //USART1初始化
TIM7_Config(84,1000); //8400分频 计数个数10000
Wwdg_Init();
printf("初始化成功!!!!!!!\r\n");
while(1)
{
// WWDG->CR |= 0x7f << 0;
}
}