打印
[应用相关]

STM32_IWDG独立看门狗功能模拟(正点原子精英板)

[复制链接]
611|3
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
看门狗是一种让系统复位的操作,功能是在系统因外界或者代码错误等因素而造成的死机后能使系统复位。看门狗其实是相当于一个递减的计数器,如我们将看门狗的初值设置为2秒那么如果在两秒内没有喂狗,系统就会复位,如果喂狗了那么计时器就会恢复初值重新计数。

下图1是IWDG相关的计算公式,只需要知道HAL库的即可。



看门狗的溢出时间使我们想要设置看门狗的初值时间。看门狗的时钟频率是根据开发板型号不同可能会存在不同,那么精英板的STM32是F1,它的看门狗时钟频率是40kHz,看门狗的预分频系数在HAL库中给出了宏定义下面对此做出讲解:



上图2就是F1相关的预分频系数设置,例如32就是最短时间为0.8毫秒最长时间就是3276.8毫秒。关于其他的相关寄存器和参数不做解释,因为编写代码的时候只需要直接设置psc和rlr。

下面通过代码直接介绍相关程序的编写。

首先我们需要编写看门狗程序的初始化代码,下图3是HAL库中独立看门狗的初始化代码,内容可以不做了解,只需要查看此代码的形参即可。




下图4就是独立看门狗初始化代码中形参的结构体。我们可以看到它有两个参数,分别是Instance和Init。Instance是独立看门狗的基地址在HAL库中对此进行了两次封装最后的封装结果就是IWDG。所以直接iwdg_handle.Instance = IWDG即可。



至于Init我们可以转到定义查看,就是下图5:



我们可以看到在这里定义了预分频系数和重装载的值所以最后我们的初始化函数就可以写成下面的样子:

这个是我iwdg.c的完整代码。

#include "./BSP/IWDG/iwdg.h"

IWDG_HandleTypeDef iwdg_handle;

void iwdg_init(uint32_t prer,uint32_t rlr)
{
       
        iwdg_handle.Instance = IWDG;        //基地址
        iwdg_handle.Init.Prescaler = prer;        //分频系数
        iwdg_handle.Init.Reload = rlr;        //重装载值
        HAL_IWDG_Init(&iwdg_handle);        //IWDG初始化
}
void feeddog(void)
{
        HAL_IWDG_Refresh(&iwdg_handle);        //喂狗
}

在初始化函数里我已经对各个参数进行了设置,为了方便改变,设置了形参来分别对应分频系数和重装载值。

分频系数应为下面HAL库中封装的值



在iwdg.c文件里我将IWDG_HandleTypeDef iwdg_handle;定义为了全局变量这是因为在下面的喂狗函数里调用的HAL库的独立看门狗喂狗函数的形参是此结构体。

那么到此独立看门狗相关函数的编写已将全部完成。

下面我将通过对LED灯的操控来模拟独立看门狗没有喂狗和喂狗情况。

#include "./SYSTEM/sys/sys.h"
#include "./SYSTEM/delay/delay.h"
#include "./SYSTEM/usart/usart.h"
#include "./BSP/LED/led.h"
#include "./BSP/KEY/key.h"
#include "./BSP/IWDG/iwdg.h"

int main(void)
{
    HAL_Init();                                 /* 初始化HAL库 */
    sys_stm32_clock_init(RCC_PLL_MUL9);         /* 设置时钟,72M */
    delay_init(72);                             /* 初始化延时函数 */
    led_init();                                 /* 初始化LED */
    key_init();                                 /* 初始化KEY */   
        iwdg_init(IWDG_PRESCALER_32,3750);          /* 初始化iwdg */   
        led0_set();
    while(1)
    {
                if(readkey0() == 1)
                {
                        feeddog();
                        led1_set();
                }
    }
}

主函数中首先对iwdg进行初始化,这里我将iwdg的初始值设置为了3秒,那么想设置成3秒我们应该选择哪个预分频参数呢,根据图2我们可以知道当预分频系数设置为32时最长时间为3276.8可以满足我们的需要,那么重装载系数我们通过公式就可以计算出它为3750。



首先用3秒乘以我们的看门狗时钟频率也就是3*40000=120000,再用得到的值除以预分频系数我们就可以得到重装载的值为120000/32=3750。

之后在主函数中未进入循环中就点亮LED0,之后在在循环中如果按下KEY0就进行喂狗和点亮LED1,那么我们就可以观察现象来判断看门狗是否工作了。即程序开始运行后的3秒内按下了KEY0使程序喂狗和点亮LED1那么看门狗的初值就会重置。再次之后的3秒内没有再次按下KEY0程序就会复位,现象就是LED1熄灭。
————————————————

                            版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

原文链接:https://blog.csdn.net/2302_77864418/article/details/139869445

使用特权

评论回复
沙发
回复就哭哭| | 2025-4-30 23:48 | 只看该作者
一旦 IWDG 被启动并开始计时,不能更改预分频和重装载值。所以确保在启动 IWDG 之前配置好所有的参数。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

37

主题

140

帖子

0

粉丝