STM32物联网项目-独立看门狗IWDG

独立看门狗IWDG

独立看门狗(IWDG)由专用的低速时钟(LSI)驱动,即使主时钟发生故障它也仍然有效。

IWDG最适合应用于那些需要看门狗作为一个在主程序之外,能够完全独立工作,并且对时间精度要求较低的场合。

IWDG主要性能

自由运行的递减计数器

时钟由独立的RC振荡器提供(可在停止和待机模式下工作)

看门狗被激活后,则在计数器计数至0x000时产生复位

IWDG功能描述

在键寄存器(IWDG_KR)中写入0xCCCC,开始启用独立看门狗;此时计数器开始从其复位值 0xFFF递减计数。当计数器计数到末尾0x000时,会产生一个复位信号(IWDG_RESET)。 无论何时,只要在键寄存器IWDG_KR中写入0xAAAA, IWDG_RLR中的值就会被重新加载到 计数器,从而避免产生看门狗复位 。

在这里插入图片描述

IWDG超时时间计算

在这里插入图片描述

由于独立看门狗是由LSI内部低速时钟提供振荡源,频率是40KHz,会经过预分频系数得到一个较小的频率,然后对重装载寄存器IWDG_RLR设定计数值,就能设定独立看门狗超时时间

例如:想要设定超时时间为2秒,则看上方表的最长时间,在32分频之后可以定时3秒多,但在16分频时定时才1.6秒左右,达不到2秒,所以选择32分频之后的预分频系数都满足要求,则

看门狗频率:40KHz / 32 = 1250Hz,也就是振动源振动1250次就定时1秒,那要定时2秒,就振动1250 * 2 = 2500次,所以重装载寄存器IWDG_RLR的设定值就为2500,这样就能使独立看门狗超过2秒后产生系统复位

CubeMX配置

独立看门狗配置

在这里插入图片描述

在这里插入图片描述

经过上面的计算,定时2秒,所以预分频系数为32,重装载值为2500,便完成了独立看门狗的初始化

在这里插入图片描述

程序

iwdg.c

独立看门狗的初始化函数比较简单,就是把CubeMX设置的预分频系数和重装载值赋给结构体变量

/* Includes ------------------------------------------------------------------*/
#include "iwdg.h"

/* USER CODE BEGIN 0 */

/* USER CODE END 0 */

IWDG_HandleTypeDef hiwdg;

/* IWDG init function */
void MX_IWDG_Init(void)
{

  hiwdg.Instance = IWDG;
  hiwdg.Init.Prescaler = IWDG_PRESCALER_32;
  hiwdg.Init.Reload = 2500;
  if (HAL_IWDG_Init(&hiwdg) != HAL_OK)
  {
    Error_Handler();
  }

}
stm32f1xx_hal_iwdg.h

HAL库的独立看门狗只有两个函数,一个是初始化函数,另一个是喂狗函数,在自己的程序中调用该喂狗函数,就能实现喂狗
在这里插入图片描述

点击喂狗函数的具体实现代码,就能看到函数底层是一个宏定义,实现功能是将IWDG_KEY_RELOAD写入键寄存器KR,这样IWDG_RLR寄存器中的值就会被重新加载到计数器,防止看门狗计数溢出复位

/**
  * @brief  Reload IWDG counter with value defined in the reload register
  *         (write access to IWDG_PR and IWDG_RLR registers disabled).
  * @param  __HANDLE__  IWDG handle
  * @retval None
  */
#define __HAL_IWDG_RELOAD_COUNTER(__HANDLE__)       WRITE_REG((__HANDLE__)->Instance->KR, IWDG_KEY_RELOAD)

而IWDG_KEY_RELOAD的值也可查看到,是0xAAAA,与文章开头提到的独立看门狗功能描述一致

#define IWDG_KEY_RELOAD                 0x0000AAAAu  /*!< IWDG Reload Counter Enable   */
MyIWDG.c

看门狗喂狗标志初始化为TRUE,喂狗函数Feed直接调用HAL库函数的喂狗函数HAL_IWDG_Refresh即可

/* Includes ------------------------------------------------------------------*/
#include "MyApplication.h"

/* Private define-------------------------------------------------------------*/

/* Private variables----------------------------------------------------------*/
static void Feed(void);
/* Public variables-----------------------------------------------------------*/
MyIWDG_t MyIWDG =
{
    TRUE,
    Feed
};
/* Private function prototypes------------------------------------------------*/

/*
* @name   Feed
* @brief  喂狗
* @param  None
* @retval None   
*/
static void Feed()
{
    //喂狗操作
    HAL_IWDG_Refresh(&hiwdg);
}
/********************************************************
  End Of File
********************************************************/
System.c

自己定义的系统运行函数中,就通过判断标志位来调用喂狗函数

/*
* @name   Run
* @brief  系统运行
* @param  None
* @retval None   
*/
static void Run()
{
    /*省略获取SHT30温湿度并往串口打印部分代码*/
    
    //独立看门狗喂狗操作
    if(MyIWDG.IWDG_Feed_Flag == TRUE)
    {
        printf("喂狗,程序正在运行\r\n");
        MyIWDG.Feed();
    }

    //延时
    HAL_Delay(1000);
}
CallBack.c

按键触发外部中断,将喂狗标志位IWDG_Feed_Flag清零,则停止喂狗,系统将复位

系统复位后,喂狗标志位IWDG_Feed_Flag又会被初始化为TRUE,所以在主函数中会执行喂狗操作,不会再造成系统复位

/*
* @name   HAL_GPIO_EXTI_Callback
* @brief  外部中断回调函数
* @param  GPIO_Pin:触发外部中断的引脚
* @retval None   
*/
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
  if(GPIO_Pin == KEY1_Pin)
  {
    MyIWDG.IWDG_Feed_Flag = FALSE;
    LED.LED_Fun(LED2,LED_ON);
    printf("停止喂狗,系统将复位!\r\n");
  }
}

实验效果

系统每隔一秒执行喂狗操作,程序正常运行,如果触摸按键1按下,则停止喂狗操作,稍后系统就会复位重启,会打印系统初始化信息,再通过喂狗让系统运行

在这里插入图片描述

在做低功耗产品时,不能使用独立看门狗,因为当系统处于待机或者停止状态时,不会进行喂狗,但独立看门狗依然会计数,就会让系统复位,无法保持低功耗模式

窗口看门狗由内部的PCLK1提供时钟,当系统待机时,PCLK也会停止工作,所以窗口看门狗也会停止工作,可以用来做低功耗产品

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值