本帖最后由 正点原子运营 于 2024-3-30 15:49 编辑
1)实验平台:正点原子 M144Z-M3 STM32F103最小系统板
2) 章节摘自【正点原子】M144Z-M3最小系统板使用指南——STM32F103版
6)正点原子STM32技术交流QQ群:725095144
本章介绍STM32F103窗口看门狗(WWDG)的使用,窗口看门狗与独立看门狗一样能够帮助CPU在进入错误状态或程序跑飞时进行复位,不过窗口看门狗相对于独立看门狗限制了“喂狗”的最小间隔,若两次“喂狗”的间隔太短,一样会产生复位。通过本章的学习,读者将学习到WWDG的使用。 本章分为如下几个小节: 15.1 硬件设计 15.2 程序设计 15.3 下载验证
15.1 硬件设计 15.1.1 例程功能 1. LED1闪烁
15.1.2 硬件资源 1. LED LED0 - PB5 2. WWDG
15.1.3 原理图 本章实验使用的窗口看门狗为STM32F103的片上资源,因此并没有相应的连接原理图。
15.2 程序设计 15.2.1 HAL库的WWDG驱动 本章实验使用到了WWDG的提前唤醒中断,提前唤醒中断指的是WWDG在“喂狗”超时即将进行复位前由WWDG产生的中断,本章实验就在WWDG的提前唤醒中断服务函数中进行“喂狗”。在使用WWDG前,需要先对其进行初始化,在初始化中,需要使能WWDG并配置WWDG的预分频系数和窗口值,还要进行使能WWDG中断的相关操作,具体的步骤如下: ①:初始化WWDG ②:在WWDG提前唤醒回调函数对其进行“喂狗” 在HAL库中对应的驱动函数如下: ①:初始化WWDG 该函数用于初始化WWDG,其函数原型如下所示: - HAL_StatusTypeDef HAL_WWDG_Init(WWDG_HandleTypeDef *hwwdg);
复制代码该函数的形参描述,如下表所示: 表15.2.1.1 函数HAL_WWDG_Init()形参描述 该函数的返回值描述,如下表所示: 表15.2.1.2 函数HAL_WWDG_Init()返回值描述 该函数需要传入WWDG的句柄指针,该句柄中就包含了WWDG的初始化配置参数结构体,该结构体的定义如下所示: - typedef struct
- {
- uint32_t Prescaler; /* 分频系数 */
- uint32_t Window; /* 窗口值 */
- uint32_t Counter; /* 计数值 */
- uint32_t EWIMode; /* 提前唤醒模式 */
- }WWDG_InitTypeDef;
复制代码该函数的使用示例,如下所示: - #include "stm32f1xx_hal.h"
- void example_fun(void)
- {
- WWDG_HandleTypeDef wwdg_handle = {0};
-
- /* 初始化WWDG */
- wwdg_handle.Instance = WWDG;
- wwdg_handle.Init.Prescaler = WWDG_PRESCALER_8;
- wwdg_handle.Init.Window = 0x5F;
- wwdg_handle.Init.Counter = 0x7F;
- wwdg_handle.Init.EWIMode = WWDG_EWI_ENABLE;
- HAL_WWDG_Init(&wwdg_handle);
- }
复制代码②:重装载WWDG的计数值 该函数用于重装载WWDG的计数值,也就是所谓的“喂狗”,其函数原型如下: - HAL_StatusTypeDef HAL_WWDG_Refresh(WWDG_HandleTypeDef *hwwdg);
复制代码该函数的形参描述,如下表所示: 表15.2.1.3 函数HAL_WWDG_Refresh()形参描述 该函数的返回值描述,如下表所示: 表15.2.1.4 函数HAL_WWDG_Refresh()返回值描述 该函数的使用示例,如下表所示: - #include "stm32f1xx_hal.h"
- void example_fun(void)
- {
- /* 重装载WWDG的计数值(喂狗) */
- HAL_WWDG_Refresh();
- }
复制代码15.2.2 看门狗驱动 本章实验的看门狗驱动主要负责向应用层提供WWDG的初始化函数,并实现WWDG的提前唤醒中断服务函数,在WWDG的提前唤醒中断服务函数中执行“喂狗”操作。本章实验中,看门狗的驱动代码包括wdt.c和wdt.h两个文件。 看门狗驱动中WWDG的初始化函数,如下所示: - /**
- *@brief 初始化窗口看门狗
- *@param counter: 计数器值
- *@param window: 窗口值
- *@param prescaler: 预分频器系数
- *@arg WWDG_PRESCALER_1: 1分频
- *@arg WWDG_PRESCALER_2: 2分频
- *@arg WWDG_PRESCALER_4: 4分频
- *@arg WWDG_PRESCALER_8: 8分频
- *@retval 无
- */
- void wwdg_init(uint32_t counter, uint32_t window, uint32_t prescaler)
- {
- g_wwdg_handler.Instance = WWDG;
- g_wwdg_handler.Init.Prescaler = prescaler;
- g_wwdg_handler.Init.Window = window;
- g_wwdg_handler.Init.Counter = counter;
- g_wwdg_handler.Init.EWIMode = WWDG_EWI_ENABLE;
- HAL_WWDG_Init(&g_wwdg_handler);
- }
复制代码从上面的代码中可以看出,WWDG的初始化函数就是调用了函数HAL_WWDG_Init()函数来初始化WWDG。 看门狗驱动中,WWDG提前唤醒回调函数,如下所示: - /**
- *@brief HAL库窗口看门狗提前唤醒中断回调函数
- *@param hwwdg: 窗口看门狗句柄
- *@retval 无
- */
- voidHAL_WWDG_EarlyWakeupCallback(WWDG_HandleTypeDef *hwwdg)
- {
- /* 喂狗窗口看门狗 */
- HAL_WWDG_Refresh(&g_wwdg_handler);
- LED1_TOGGLE();
- }
复制代码可以看到,在窗口看门狗的提前唤醒回调函数中,对WWDG进行了喂狗操作,同时还对LED1的状态进行了以此翻转(方便观察)。 15.2.3 实验应用代码 本章实验的应用代码,如下所示: - int main(void)
- {
- HAL_Init(); /* 初始化HAL库 */
- sys_stm32_clock_init(RCC_PLL_MUL9); /* 配置时钟,72MHz */
- delay_init(72); /* 初始化延时 */
- usart_init(115200); /* 初始化串口 */
- led_init(); /* 初始化LED */
- wwdg_init(0x7F, 0x5F, WWDG_PRESCALER_8); /* 初始化窗口看门狗 */
-
- while (1)
- {
-
- }
- }
复制代码可以看到应用代码中,LED初始化后会初始化窗口看门狗,若窗口看门狗正常被“喂狗”,则可以看到LED1闪烁。 15.3 下载验证 在完成编译和烧录操作后,可以看LED1不断闪烁,说明WWDG“喂狗”正常。 |