【stm32】独立看门狗使用方法

1. 概述

简介
  独立看门狗本质上是一个定时器。该定时器是一个 12 位的递减计数器,当计数器的值减到 0 的时候,就会产生一个复位信号。如果在计数没减到 0 之前,重置计数器的值,那么就不会产生复位信号,重置计数器的数值我们称为喂狗。看门狗功能由 VDD 电压域供电,在停止模式和待机模式下仍然可以工作。

应用场景

  1. 系统复位和故障恢复: 独立看门狗通常配置为定时器,如果系统在特定时间内没有喂狗(即向看门狗发送特定的喂狗信号),看门狗将认为系统出现了故障或挂起,触发系统复位。这有助于在系统发生死锁或其他异常情况时,强制系统重新启动,使系统回到稳定状态。

  2. 防止程序执行进入无限循环: 在一些嵌入式系统中,程序可能由于软件错误而陷入无限循环或者不断重复相同的操作。独立看门狗可以防止这种情况发生,因为它会定期进行复位操作,确保程序在特定时间内正常运行。

  3. 电源管理: 在一些低功耗应用中,系统可能会进入某种睡眠状态以节省能量。独立看门狗可以用于监测系统是否按照预期唤醒,以及在唤醒后是否正常运行。如果系统在规定的时间内没有完成唤醒和正常运行,独立看门狗可以引发复位,确保系统重新进入正常工作状态。

  4. 固件更新和远程维护: 在一些嵌入式系统中,独立看门狗可以用于监测固件更新过程。如果更新在规定时间内没有完成,独立看门狗可能会引发复位,确保系统不会永久处于无法正常运行的状态。

2.原理分析

系统框图
在这里插入图片描述

IWDG 有一个输入(时钟 LSI),经过一个 8 位的可编程预分频器提供时钟给一个 12 位递减计数器,满足条件就会输出一个复位信号( IWDG_RESET),而我们可以通过键寄存器 IWDG_KR在适当的时候重置计数器,使得程序在需要的条件下才能进行复位。

由于看门狗所需要的时钟精度并不高,因此我们可以直接使用内部的低速时钟。

IWDG_PR 和 IWDG_RLR 寄存器具有写保护功能。要修改这两个寄存器的值,必须先向
IWDG_KR 寄存器中写入 0x5555。将其他值写入这个寄存器将会打乱操作顺序,寄存器将重新被保护。重装载操作(即写入 0xAAAA)也会启动写保护功能。

3.实验和代码

功能描述:

我们使用正点原子stm32mini开发板,在配置看门狗后, LED0 将常亮,如果 KEY_UP 按键按下,就喂狗,只要 KEY_UP 不停的按,看门狗就一直不会产生复位,保持 LED0 的常亮,一旦超过看门狗定溢出时间。还没按,那么将会导致程序重启,这将导致 LED0 熄灭一次。

  • LED0 – PA8
  • WK_UP - PA0
//主函数代码
int main(void)
{
    HAL_Init();                             /* HAL库初始化 */
    sys_stm32_clock_init(RCC_PLL_MUL9);     /* 设置时钟, 72Mhz */
    delay_init(72);                         /* 延时初始化 */
    usart_init(115200);                     /* 串口初始化为115200 */
    led_init();                             /* 初始化LED */
    key_init();                             /* 初始化按键 */
    delay_ms(100);                          /* 延时100ms再初始化看门狗,LED0的变化"可见" */
    iwdg_init(IWDG_PRESCALER_64, 625);      /* 预分频数为64,重载值为625,溢出时间为1s */
    LED0(0);                                /* 点亮LED0(红灯) */

    while (1)
    {
        if (key_scan(0) == WKUP_PRES)       /* 如果WK_UP按下,则喂狗 */
        {
            iwdg_feed();                    /* 喂狗 */
        }

        delay_ms(10);
    }
}

//iwdg功能代码
IWDG_HandleTypeDef iwdg_handle; /* 独立看门狗句柄 */

void iwdg_init(uint8_t prer, uint16_t rlr)
{
    iwdg_handle.Instance = IWDG;
    iwdg_handle.Init.Prescaler = prer; /* 设置IWDG分频系数 */
    iwdg_handle.Init.Reload = rlr;     /* 重装载值 */
    HAL_IWDG_Init(&iwdg_handle);       /* 初始化IWDG并使能 */
}

void iwdg_feed(void)
{
    HAL_IWDG_Refresh(&iwdg_handle);  /* 重装载计数器 */
}

  • 7
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值