本帖最后由 正点原子运营 于 2024-3-30 15:42 编辑
1)实验平台:正点原子 M144Z-M3 STM32F103最小系统板
2) 章节摘自【正点原子】M144Z-M3最小系统板使用指南——STM32F103版
6)正点原子STM32技术交流QQ群:725095144
本章介绍STM32F103独立看门狗(IWDG)的使用,独立看门狗能够帮助CPU在进入错误状态或程序跑飞时进行复位。通过本章的学习,读者将学习到IWDG的使用。 本章分为如下几个小节: 14.1 硬件设计 14.2 程序设计 14.3 下载验证
14.1 硬件设计 14.1.1 例程功能 1. 若每间隔1秒内按下一次WKUP按键,则LED0常亮,否则LED0闪烁
14.1.2 硬件资源 1. LED LED0 - PB5 2. 按键 WKUP - PA0 3. IWDG
14.1.3 原理图 本章实验使用的独立看门狗为STM32F103的片上资源,因此并没有相应的连接原理图。
14.2 程序设计 14.2.1 HAL库的IWDG驱动 在使用IWDG前,需要先对其进行初始化,在初始化操作中要开启IWDG并配置IWDG的预分频系数和重装载值,预分频系数和重装载值就决定了IWDG单次溢出的时间,因此这两个值应该根据实际的应用场景妥善进行设置,若IWDG的溢出时间太长,则对异常情况的反应将变得迟钝,但若设置地太短,则会误触发复位,因此需要妥善设置。使用IWDG的具体步骤如下: ①:初始化IWDG ②:在IWDG溢出前不断地进行“喂狗”操作 在HAL库中对应的驱动函数如下: ①:初始化IWDG 该函数用于初始化IWDG,其函数原型如下所示: - HAL_StatusTypeDef HAL_IWDG_Init(IWDG_HandleTypeDef *hiwdg);
复制代码该函数的形参描述,如下表所示: 表14.2.1.1 函数HAL_IWDG_Init()形参描述 该函数的返回值描述,如下表所示: 表14.2.1.2 函数HAL_IWDG_Init()返回值描述 该函数需要传入IWDG的句柄指针,该句柄中就包含了IWDG的初始化配置参数结构体,该结构体的定义如下所示: - typedef struct
- {
- uint32_t Prescaler; /* 分频系数 */
- uint32_t Reload; /* 重装载值 */
- }IWDG_InitTypeDef;
复制代码该函数的使用示例,如下所示: - #include "stm32f1xx_hal.h"
- void example_fun(void)
- {
- IWDG_HandleTypeDef iwdg_handle = {0};
-
- /* 初始化IWDG */
- iwdg_handle.Instance = IWDG;
- iwdg_handle.Init.Prescaler = IWDG_PRESCALER_64;
- iwdg_handle.Init.Reload = 500;
- HAL_IWDG_Init(&iwdg_handle);
- }
复制代码②:重装载IWDG 该函数用于重装载IWDG,也就是所谓的“喂狗”,其函数原型如下所示: - HAL_StatusTypeDef HAL_IWDG_Refresh(IWDG_HandleTypeDef *hiwdg);
复制代码该函数的形参描述,如下表所示: 表14.2.1.3 函数HAL_IWDG_Refresh()形参描述 该函数的返回值描述,如下表所示: 表14.2.1.4 函数HAL_IWDG_Refresh()返回值描述 该函数的使用示例,如下所示: - #include "stm32f1xx_hal.h"
- void example_fun(void)
- {
- /* 重装载IWDG(喂狗) */
- HAL_IWDG_Refresh();
- }
复制代码
14.2.2 看门狗驱动 本章实验的看门狗驱动主要负责向应用层提供IWDG初始化和喂狗的操作函数,本章实验中,看门狗的驱动代码包括wdg.c和wdg.h两个文件。 看门狗驱动中,IWDG的初始化函数,如下所示: - /**
- *@brief 初始化独立看门狗
- *@param prescaler: 预分频器系数
- *@arg IWDG_PRESCALER_4 : 4分频
- *@arg IWDG_PRESCALER_8 : 8分频
- *@arg IWDG_PRESCALER_16 : 16分频
- *@arg IWDG_PRESCALER_32 : 32分频
- *@arg IWDG_PRESCALER_64 : 64分频
- *@arg IWDG_PRESCALER_128: 128分频
- *@arg IWDG_PRESCALER_256: 256分频
- *@param reload: 自动重装载值(0~0xFFF)
- *@retval 无
- */
- void iwdg_init(uint32_t prescaler, uint32_t reload)
- {
- g_iwdg_handler.Instance = IWDG;
- g_iwdg_handler.Init.Prescaler = prescaler;
- g_iwdg_handler.Init.Reload = reload;
- HAL_IWDG_Init(&g_iwdg_handler);
- }
复制代码IWDG的初始化函数中使能了IWDG并配置其预分频系数和重装载值,并进行了一次“喂狗”防止IWDG一使能就溢出引发复位。 看门狗驱动中,IWDG的“喂狗”函数,如下所示: - /**
- *@brief 喂狗独立看门狗
- *@param 无
- *@retval 无
- */
- void iwdg_feed(void)
- {
- HAL_IWDG_Refresh(&g_iwdg_handler);
- }
复制代码该函数很简单,就是重装载IWDG的计数值。
14.2.3 实验应用代码 本章实验的应用代码,如下所示: - int main(void)
- {
- uint8_t key;
-
- HAL_Init(); /* 初始化HAL库 */
- sys_stm32_clock_init(RCC_PLL_MUL9); /* 配置时钟,72MHz */
- delay_init(72); /* 初始化延时 */
- usart_init(115200); /* 初始化串口 */
- led_init(); /* 初始化LED */
- key_init(); /* 初始化按键 */
- iwdg_init(IWDG_PRESCALER_64, 625); /* 初始化独立看门狗,溢出时间约1秒 */
-
- delay_ms(100);
- LED0(0);
-
- while (1)
- {
- key = key_scan(1);
- if (key == WKUP_PRES) /* WKUP按键被按下 */
- {
- iwdg_feed(); /* 喂狗独立看门狗 */
- }
-
- delay_ms(10);
- }
- }
复制代码可以看到应用代码中,LED初始化后,LED0会处于默认的熄灭状态100毫秒,随后初始化IWDG并点亮LED0,接着在while循环中重复判断WKUP按键是否被按下,若按下则进行“喂狗”操作,若在IWDG溢出前都为按下WKUP按键,则IWDG会触发复位,复位会导致LED0熄灭大约100毫秒(便于观察)。
14.3 下载验证 在完成编译和烧录操作后,可以看到板子上的LED0每间隔一段时间(大约1秒)就闪烁一次,这是因为IWDG不断地溢出,导致的复位。接下来若以时间间隔小于1秒(大约)的速度频繁地按下WKUP按键,则可以在IWDG溢出前及时“喂狗”,具体的现象为LED0不再闪烁。 |