目录
- 一、独立看门狗
-
- 1. IWDG简介
- 2. IWDG工作原理及框图
- 3. IWDG寄存器及函数介绍
- 4. IWDG溢出时间计算
- 5. IWDG配置步骤
- 6. 小实验:独立看门狗喂狗实验
- 二、窗口看门狗
-
- 1. WWDG简介
- 2. WWDG工作原理及框图
- 3. WWDG寄存器及函数介绍
- 4. WWDG溢出时间计算
- 5. WWDG配置步骤
- 6. 小实验:窗口看门狗喂狗实验
一、独立看门狗
1. IWDG简介
独立看门狗(Independent Watchdog,通常缩写为IWDG)主要作用是主要用于检测外界电磁干扰,或硬件异常导致的程序跑飞问题。
- IWDG本质上是一个12位的递减计数器。当计数器的值从某个初始值开始递减,并一直减到0时,系统会产生一个复位信号(IWDG_RESET)。CPU在接收到这个复位信号后,会重新启动系统,以确保系统从可能的错误或死锁状态中恢复。
- 在计数器的值减到0之前,如果程序通过特定的“喂狗”操作(即重置计数器的值)来刷新计数器,那么就不会产生复位信号,系统将继续正常运行。这种“喂狗”操作通常是由程序在正常运行时定期执行的,以确保IWDG不会因计数器超时而产生复位信号。
- 它使用专用的低速时钟(LSI)作为时钟源,即使在主时钟发生故障时,IWDG仍然能够继续运行。IWDG可以在停止模式和待机模式下工作,确保在这些模式下系统仍然受到保护。
2. IWDG工作原理及框图


3. IWDG寄存器及函数介绍






4. IWDG溢出时间计算

1Tout:看门狗溢出时间 2fIWDG:看门狗的时钟源频率 3psc:看门狗预分频系数 4rlr:看门狗重装载值 5

5. IWDG配置步骤

6. 小实验:独立看门狗喂狗实验
实验目的
配置 IWDG 溢出时间为 1 秒左右,并验证未及时喂狗时系统将被复位。
代码实现
main.c
1#include "sys.h" 2#include "uart1.h" 3#include "delay.h" 4#include "led.h" 5#include "uart1.h" 6#include "iwdg.h" 7 8int main(void) 9{ 10 HAL_Init(); /* 初始化HAL库 */ 11 stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */ 12 //LED初始化 13 led_init(); 14 uart1_init(115200); 15 iwdg_init(IWDG_PRESCALER_32,1250 - 1); 16 printf("hello world\r\n"); 17 printf("狗儿肚子饿了,再不喂它的话就咬人了\r\n"); 18 19 if(__HAL_RCC_GET_FLAG(RCC_FLAG_IWDGRST) != RESET){ 20 printf("独立看门狗复位\r\n"); 21 __HAL_RCC_CLEAR_RESET_FLAGS(); 22 }else{ 23 printf("其他复位重启\r\n"); 24 } 25 26 while(1) 27 { 28 delay_ms(500); 29 iwdg_feed(); 30 printf("狗儿已经喂饱了,不会咬人了!\r\n"); 31 } 32} 33
iwdg.c
1#include "iwdg.h" 2 3IWDG_HandleTypeDef iwdg_handle = {0}; 4 5//独立看门口初始化 6void iwdg_init(uint8_t psc, uint16_t rlr) 7{ 8 iwdg_handle.Instance = IWDG; 9 iwdg_handle.Init.Prescaler = psc; 10 iwdg_handle.Init.Reload = rlr; 11 HAL_IWDG_Init(&iwdg_handle); 12} 13 14//喂狗函数 15void iwdg_feed(void) 16{ 17 HAL_IWDG_Refresh(&iwdg_handle); 18} 19 20
iwdg.h
1#ifndef __IWDG_H__ 2#define __IWDG_H__ 3 4#include "sys.h" 5 6//独立看门口初始化 7void iwdg_init(uint8_t psc, uint16_t rlr); 8//喂狗函数 9void iwdg_feed(void); 10 11#endif 12
二、窗口看门狗
1. WWDG简介
窗口看门狗用于监测单片机程序运行时效是否精准,主要检测软件异常,一般用于需要精准检测程序运行时间的场合。
窗口看门狗的本质是一个能产生系统复位信号和提前唤醒中断的6位计数器。产生复位条件:
- 当递减计数器值从 0x40 减到 0x3F 时复位(即T6位跳变到0)。
- 计数器的值大于 W[6:0] 值时喂狗会复位。
产生中断条件:
- 当递减计数器等于 0x40 时可产生提前唤醒中断 (EWI)。
- 在窗口期内重装载计数器的值,防止复位,也就是所谓的喂狗。
2. WWDG工作原理及框图


3. WWDG寄存器及函数介绍





4. WWDG溢出时间计算

5. WWDG配置步骤

6. 小实验:窗口看门狗喂狗实验
实验目的
开启窗口看门狗,计数器值设置为 0X7F ,窗口值设置为 0X5F ,预分频系数为 8 。在 while 循环里喂狗,同时翻转 LED1 状态;在提前唤醒中断服务函数进行喂狗,同时翻转 LED2 状态。

代码实现
main.c
1#include "sys.h" 2#include "uart1.h" 3#include "delay.h" 4#include "led.h" 5#include "uart1.h" 6#include "wwdg.h" 7 8int main(void) 9{ 10 HAL_Init(); /* 初始化HAL库 */ 11 stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */ 12 //LED初始化 13 led_init(); 14 //串口初始化 15 uart1_init(115200); 16 //窗口看门狗初始化 17 wwdg_init(0x7F, 0x5F, WWDG_PRESCALER_8); 18 19 if(__HAL_RCC_GET_FLAG(RCC_FLAG_WWDGRST) != RESET){ 20 printf("独立看门狗复位\r\n"); 21 __HAL_RCC_CLEAR_RESET_FLAGS(); 22 }else{ 23 printf("其他复位重启\r\n"); 24 } 25 26 while(1) 27 { 28 delay_ms(50); 29 wwdg_feed(); 30 led2_toggle(); 31 } 32} 33
wwdg.c
1#include "wwdg.h" 2#include "led.h" 3 4WWDG_HandleTypeDef wwdg_handle = {0}; 5//窗口看门狗初始化 6void wwdg_init(uint8_t tr, uint8_t wr , uint32_t psc) 7{ 8 wwdg_handle.Instance = WWDG; 9 //设置定时器重装载值 10 wwdg_handle.Init.Counter = tr; 11 //设置窗口值 12 wwdg_handle.Init.Window = wr; 13 //设置分频系数 14 wwdg_handle.Init.Prescaler = psc; 15 //提前唤醒中断使能标志 16 wwdg_handle.Init.EWIMode = WWDG_EWI_ENABLE;; 17 HAL_WWDG_Init(&wwdg_handle); 18} 19 20//硬件相关初始化 21void HAL_WWDG_MspInit(WWDG_HandleTypeDef *hwwdg) 22{ 23 //打开看门口时钟 24 __HAL_RCC_WWDG_CLK_ENABLE(); 25 //设置中断优先级 26 HAL_NVIC_SetPriority(WWDG_IRQn, 2, 2); 27 //使能中断 28 HAL_NVIC_EnableIRQ(WWDG_IRQn); 29} 30 31//中断服务函数 32void WWDG_IRQHandler(void) 33{ 34 //公共服务函数 35 HAL_WWDG_IRQHandler(&wwdg_handle); 36} 37 38//喂狗函数 39void wwdg_feed(void) 40{ 41 HAL_WWDG_Refresh(&wwdg_handle); 42} 43 44//中断回调函数 45void HAL_WWDG_EarlyWakeupCallback(WWDG_HandleTypeDef *hwwdg) 46{ 47 //喂狗 48 //wwdg_feed(); 49 led2_toggle(); 50} 51
wwdg.h
1#ifndef __WWDG_H__ 2#define __WWDG_H__ 3 4#include "sys.h" 5 6 7//喂狗函数 8void wwdg_feed(void); 9void wwdg_init(uint8_t tr, uint8_t wr , uint32_t psc); 10 11#endif 12
《【STM32】看门狗》 是转载文章,点击查看原文。