Skip to content

Commit 96e39ca

Browse files
Auto-update blog content
1 parent 21acdfc commit 96e39ca

File tree

70 files changed

+19640
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

70 files changed

+19640
-0
lines changed
Lines changed: 319 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,319 @@
1+
---
2+
layout: post
3+
title: "STM32看门狗"
4+
date: 2025-10-28T08:44:39+0800
5+
description: "独立看门狗(IndependentWatchdog,通常缩写为IWDG)主要作用是主要用于检测外界电磁干扰,或硬件异常导致的程序跑飞问题。IWDG本质上是一个12位的递减计数器。当计数器的值从某个初始值开始递减,并一直减到0时,系统会产生一个复位信号(IWDG_RESET)。CPU在接收到这个复位信号后,会重新启动系统,以确保系统从可能的错误或死锁状态中恢复。在计数器的值减到0之前,如果程序通过特定的“喂狗”操作(即重置计数器的值)来刷新计数器,那么就不会产生复位信号,系统将继续正常运行。"
6+
keywords: "【STM32】看门狗"
7+
categories: ['未分类']
8+
tags: ['嵌入式硬件', 'Stm']
9+
artid: "154004388"
10+
arturl: "https://blog.csdn.net/qq_62361050/article/details/154004388"
11+
image:
12+
path: https://api.vvhan.com/api/bing?rand=sj&artid=154004388
13+
alt: "STM32看门狗"
14+
render_with_liquid: false
15+
featuredImage: https://bing.ee123.net/img/rand?artid=154004388
16+
featuredImagePreview: https://bing.ee123.net/img/rand?artid=154004388
17+
cover: https://bing.ee123.net/img/rand?artid=154004388
18+
img: https://bing.ee123.net/img/rand?artid=154004388
19+
---
20+
21+
22+
23+
# 【STM32】看门狗
24+
25+
26+
[![](https://csdnimg.cn/release/blogv2/dist/pc/img/activeVector.png)
27+
『AI先锋杯·14天征文挑战第7期』
28+
10w+人浏览
29+
319人参与
30+
31+
![](https://csdnimg.cn/release/blogv2/dist/pc/img/arrowright-line-White.png)](https://activity.csdn.net/writing?id=11005)
32+
33+
## 一、独立看门狗
34+
35+
### 1. IWDG简介
36+
37+
独立看门狗(Independent Watchdog,通常缩写为IWDG)主要作用是主要用于检测外界电磁干扰,或硬件异常导致的程序跑飞问题。
38+
39+
* IWDG本质上是一个12位的递减计数器。当计数器的值从某个初始值开始递减,并一直减到0时,系统会产生一个复位信号(IWDG_RESET)。CPU在接收到这个复位信号后,会重新启动系统,以确保系统从可能的错误或死锁状态中恢复。
40+
* 在计数器的值减到0之前,如果程序通过特定的“喂狗”操作(即重置计数器的值)来刷新计数器,那么就不会产生复位信号,系统将继续正常运行。这种“喂狗”操作通常是由程序在正常运行时定期执行的,以确保IWDG不会因计数器超时而产生复位信号。
41+
* 它使用专用的低速时钟(LSI)作为时钟源,即使在主时钟发生故障时,IWDG仍然能够继续运行。IWDG可以在停止模式和待机模式下工作,确保在这些模式下系统仍然受到保护。
42+
43+
### 2. IWDG工作原理及框图
44+
45+
![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/c34cf379f03b4ba59efc3c954ade5a45.png)
46+
47+
![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/92c6341ec1e44a52a3b4fa7219c9941a.png)
48+
49+
### 3. IWDG寄存器及函数介绍
50+
51+
![v](https://i-blog.csdnimg.cn/direct/76cdf08ca18349bf8cf58ca7b4f3ce6e.png)
52+
53+
### 4. IWDG溢出时间计算
54+
55+
![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/dbd06a500f38419e960e4d9da7b45d6a.png)
56+
57+
```c
58+
Tout:看门狗溢出时间
59+
fIWDG:看门狗的时钟源频率
60+
psc:看门狗预分频系数
61+
rlr:看门狗重装载值
62+
63+
```
64+
65+
![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/74ab576a4156439480bcda879310c23e.png)
66+
67+
### 5. IWDG配置步骤
68+
69+
![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/0518517f931e45899110cea75eff0e9e.png)
70+
71+
### 6. 小实验:独立看门狗喂狗实验
72+
73+
**实验目的**
74+
75+
配置 IWDG 溢出时间为 1 秒左右,并验证未及时喂狗时系统将被复位。
76+
77+
**代码实现**
78+
79+
main.c
80+
81+
```c
82+
#include "sys.h"
83+
#include "uart1.h"
84+
#include "delay.h"
85+
#include "led.h"
86+
#include "uart1.h"
87+
#include "iwdg.h"
88+
89+
int main(void)
90+
{
91+
HAL_Init(); /* 初始化HAL库 */
92+
stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */
93+
//LED初始化
94+
led_init();
95+
uart1_init(115200);
96+
iwdg_init(IWDG_PRESCALER_32,1250 - 1);
97+
printf("hello world\r\n");
98+
printf("狗儿肚子饿了,再不喂它的话就咬人了\r\n");
99+
100+
if(__HAL_RCC_GET_FLAG(RCC_FLAG_IWDGRST) != RESET){
101+
printf("独立看门狗复位\r\n");
102+
__HAL_RCC_CLEAR_RESET_FLAGS();
103+
}else{
104+
printf("其他复位重启\r\n");
105+
}
106+
107+
while(1)
108+
{
109+
delay_ms(500);
110+
iwdg_feed();
111+
printf("狗儿已经喂饱了,不会咬人了!\r\n");
112+
}
113+
}
114+
115+
```
116+
117+
iwdg.c
118+
119+
```c
120+
#include "iwdg.h"
121+
122+
IWDG_HandleTypeDef iwdg_handle = {0};
123+
124+
//独立看门口初始化
125+
void iwdg_init(uint8_t psc, uint16_t rlr)
126+
{
127+
iwdg_handle.Instance = IWDG;
128+
iwdg_handle.Init.Prescaler = psc;
129+
iwdg_handle.Init.Reload = rlr;
130+
HAL_IWDG_Init(&iwdg_handle);
131+
}
132+
133+
//喂狗函数
134+
void iwdg_feed(void)
135+
{
136+
HAL_IWDG_Refresh(&iwdg_handle);
137+
}
138+
139+
140+
```
141+
142+
iwdg.h
143+
144+
```c
145+
#ifndef __IWDG_H__
146+
#define __IWDG_H__
147+
148+
#include "sys.h"
149+
150+
//独立看门口初始化
151+
void iwdg_init(uint8_t psc, uint16_t rlr);
152+
//喂狗函数
153+
void iwdg_feed(void);
154+
155+
#endif
156+
157+
```
158+
159+
## 二、窗口看门狗
160+
161+
### 1. WWDG简介
162+
163+
窗口看门狗用于监测单片机程序运行时效是否精准,主要检测软件异常,一般用于需要精准检测程序运行时间的场合。
164+
165+
窗口看门狗的本质是一个能产生系统复位信号和提前唤醒中断的6位计数器。产生复位条件:
166+
167+
* 当递减计数器值从 0x40 减到 0x3F 时复位(即T6位跳变到0)。
168+
* 计数器的值大于 W[6:0] 值时喂狗会复位。
169+
170+
产生中断条件:
171+
172+
* 当递减计数器等于 0x40 时可产生提前唤醒中断 (EWI)。
173+
* 在窗口期内重装载计数器的值,防止复位,也就是所谓的喂狗。
174+
175+
### 2. WWDG工作原理及框图
176+
177+
![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/3ce30163ad474621984040742b8c72e9.png)
178+
179+
![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/6fa47729c04f40bc94b4b81d1adaef03.png)
180+
181+
### 3. WWDG寄存器及函数介绍
182+
183+
![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/021745ea8e174d23b62e62f7122a06ff.png)
184+
![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/7991ff88ad124972931aacb904a6245e.png)
185+
![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/0836b64be0994e7cbfe813a5e7b702ac.png)
186+
![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/3190fccefdd042de93deba5a0ca2beae.png)
187+
![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/b626d0418e9a4585a5c4a2fe2ee6a3a9.png)
188+
189+
### 4. WWDG溢出时间计算
190+
191+
![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/0f3493cc29ab44b1bf2303cd18757d3f.png)
192+
193+
### 5. WWDG配置步骤
194+
195+
![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/535e6b89c80448bb92ae1aca69c32ed2.png)
196+
197+
### 6. 小实验:窗口看门狗喂狗实验
198+
199+
**实验目的**
200+
201+
开启窗口看门狗,计数器值设置为 0X7F ,窗口值设置为 0X5F ,预分频系数为 8 。在 while 循环里喂狗,同时翻转 LED1 状态;在提前唤醒中断服务函数进行喂狗,同时翻转 LED2 状态。
202+
203+
![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/1c358e97115d4d7a96e973aefd885c57.png)
204+
205+
**代码实现**
206+
207+
main.c
208+
209+
```c
210+
#include "sys.h"
211+
#include "uart1.h"
212+
#include "delay.h"
213+
#include "led.h"
214+
#include "uart1.h"
215+
#include "wwdg.h"
216+
217+
int main(void)
218+
{
219+
HAL_Init(); /* 初始化HAL库 */
220+
stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */
221+
//LED初始化
222+
led_init();
223+
//串口初始化
224+
uart1_init(115200);
225+
//窗口看门狗初始化
226+
wwdg_init(0x7F, 0x5F, WWDG_PRESCALER_8);
227+
228+
if(__HAL_RCC_GET_FLAG(RCC_FLAG_WWDGRST) != RESET){
229+
printf("独立看门狗复位\r\n");
230+
__HAL_RCC_CLEAR_RESET_FLAGS();
231+
}else{
232+
printf("其他复位重启\r\n");
233+
}
234+
235+
while(1)
236+
{
237+
delay_ms(50);
238+
wwdg_feed();
239+
led2_toggle();
240+
}
241+
}
242+
243+
```
244+
245+
wwdg.c
246+
247+
```c
248+
#include "wwdg.h"
249+
#include "led.h"
250+
251+
WWDG_HandleTypeDef wwdg_handle = {0};
252+
//窗口看门狗初始化
253+
void wwdg_init(uint8_t tr, uint8_t wr , uint32_t psc)
254+
{
255+
wwdg_handle.Instance = WWDG;
256+
//设置定时器重装载值
257+
wwdg_handle.Init.Counter = tr;
258+
//设置窗口值
259+
wwdg_handle.Init.Window = wr;
260+
//设置分频系数
261+
wwdg_handle.Init.Prescaler = psc;
262+
//提前唤醒中断使能标志
263+
wwdg_handle.Init.EWIMode = WWDG_EWI_ENABLE;;
264+
HAL_WWDG_Init(&wwdg_handle);
265+
}
266+
267+
//硬件相关初始化
268+
void HAL_WWDG_MspInit(WWDG_HandleTypeDef *hwwdg)
269+
{
270+
//打开看门口时钟
271+
__HAL_RCC_WWDG_CLK_ENABLE();
272+
//设置中断优先级
273+
HAL_NVIC_SetPriority(WWDG_IRQn, 2, 2);
274+
//使能中断
275+
HAL_NVIC_EnableIRQ(WWDG_IRQn);
276+
}
277+
278+
//中断服务函数
279+
void WWDG_IRQHandler(void)
280+
{
281+
//公共服务函数
282+
HAL_WWDG_IRQHandler(&wwdg_handle);
283+
}
284+
285+
//喂狗函数
286+
void wwdg_feed(void)
287+
{
288+
HAL_WWDG_Refresh(&wwdg_handle);
289+
}
290+
291+
//中断回调函数
292+
void HAL_WWDG_EarlyWakeupCallback(WWDG_HandleTypeDef *hwwdg)
293+
{
294+
//喂狗
295+
//wwdg_feed();
296+
led2_toggle();
297+
}
298+
299+
```
300+
301+
wwdg.h
302+
303+
```c
304+
#ifndef __WWDG_H__
305+
#define __WWDG_H__
306+
307+
#include "sys.h"
308+
309+
310+
//喂狗函数
311+
void wwdg_feed(void);
312+
void wwdg_init(uint8_t tr, uint8_t wr , uint32_t psc);
313+
314+
#endif
315+
316+
```
317+
318+
319+

0 commit comments

Comments
 (0)