自学内容网 自学内容网

细说STM32F407单片机独立看门狗IWDG的原理及使用方法

目录

一、独立看门狗的工作原理

二、独立看门狗的HAL驱动程序

1、初始化函数HAL_IWDG_Init()

2、刷新看门狗的函数HAL_IWDG_Refresh()

3、宏函数

三、独立看门狗使用示例

1、项目动作说明

2、工程配置

(1)DEBUG、USART6、GPIO、CodeGenrator

(2) 时钟

(3) RTC

(4)IWDG

(5)NVIC

3、软件设计

(1)KEYLED

(2) main.c

4、运行与调试


        看门狗(Watchdog)就是MCU上的一种特殊的定时器,用于监视系统的运行,在发生错误(例如程序出现死循环)时,能自动使系统复位。STM32F407上有1个独立看门狗和1个窗口看门狗,这两个看门狗的作用不一样。

一、独立看门狗的工作原理

        独立看门狗(Independent Watchdog,IWDG)是由内部32kHz低速时钟LSI驱动的自由运行的12位递减计数器。LSI在时钟树上的位置如图所示。“独立看门狗”简称为“看门狗”。

 

        独立看门狗内部还可以对LSI时钟进行分频,分频后的时钟作为计数器的时钟信号。在预分频器寄存器IWDG_PR里,有PR[2:0]用于设置分频系数,分频系数从4、8、16到256。系统复位时,IWDG的12位递减计数器的值是4095。启动IWDG后,计数器就递减计数,当计数器值变为0的时候,就会使系统产生复位。

        独立看门狗有一个重载寄存器IWDG_RLR,可以设置一个12位的重载值,例如4000。在看门狗的递减计数器的值变为0之前,将IWDG_RLR里的值重新载入看门狗计数器,就可以避免产生复位。

        独立看门狗还有一个关键字寄存器IWDG_KR,其KEY[15:0]是一个只可以写的关键字。写入不同的关键字有不同的作用。

  • 写入0xAAAA时,重载寄存器IWDG_RLR中的12位值就会被写入计数器,从而使计数器从头开始递减计数,避免系统复位。此操作称为刷新看门狗。
  • 写入0x5555后,才可以修改预分频器寄存器IWDG_PR和重载寄存器IWDG_RLR的内容。
  • 写入0xCCCC时,启动独立看门狗。

        重载值为4095时独立看门狗的超时:

预分频系数超时/ms
/4512 
/81024 
/162048 
/324096 
/648192 
/12816384 
/25632768 

二、独立看门狗的HAL驱动程序

        独立看门狗的HAL驱动程序头文件是stm32f4xx_hal_iwdg.h,独立看门狗的驱动函数比较少,只有2个常规函数和几个宏函数。独立看门狗没有中断。

1、初始化函数HAL_IWDG_Init()

        函数HAL_IWDG_Init()用于初始化独立看门狗,其原型定义如下:

HAL_StatusTypeDef HAL_IWDG_Init(IWDG_HandleTypeDef *hiwdg);

        其中,参数hiwdg是IWDG_HandleTypeDef结构体指针,是看门狗对象指针。独立看门狗初始化后就自动启动了,且无法关闭。

        在CubeMX生成的外设初始化代码中,会定义一个独立看门狗外设对象变量,即

IWDG_HandleTypeDef hiwdg; //独立看门狗外设对象变量

        结构体IWDG_HandleTypeDef的定义如下,各成员变量的意义见注释:

typedef struct
{
    IWDG_TypeDef *Instance;    //IWDG寄存器基址
    IWDG_InitTypeDef Init;     //IWDG的参数
}IWDG_HandleTypeDef;

        其中的成员变量Init是结构体类型IWDG_InitTypeDef,它定义了IWDG的参数,这个结构体定义如下,各成员变量的意义见注释:

typedef struct
{
    uint32_t Prescaler; //IWDG预分频系数,也就是预分频寄存器工WDG_PR里的PR[2:0]
    uint32_t Reload;    //IWDG计数器重载值,也就是重载寄存器IWDG_RLR的值
}IWDG_InitTypeDef;

2、刷新看门狗的函数HAL_IWDG_Refresh()

        函数HAL_IWDG_Refresh()用于刷新看门狗,就是将重载寄存器IWDG_RLR的值重新载入看门狗计数器,避免产生系统复位。函数HAL_IWDG_Refresh()的原型定义如下,只需使用IWDG对象指针作为函数参数:

HAL_StatusTypeDef HAL_IWDG_Refresh(IWDG_HandleTypeDef *hiwdg);

3、宏函数

        文件stm32f4xx_hal_iwdg.h还有几个主要的宏函数,这些函数的输入参数__HANDLE__是独立看门狗对象指针。

  • __HAL_IWDG_START(__HANDLE__),启动独立看门狗,就是向关键字寄存器IWDG_KR写入0x0000CCCC。
  • __HAL_IWDG_RELOAD_COUNTER(__HANDLE__),重置看门狗计数器的值,就是向关键字寄存器IWDG_KR写入0x0000AAAA,这会导致重载寄存器IWDG_RLR中的值载入看门狗计数器。这个宏函数与函数HAL_IWDG_Refresh()的功能相同。
  • __IWDG_ENABLE_WRITE_ACCESS(__HANDLE__),使预分频寄存器IWDG_PR和重载寄存器IWDG_RLR变为可写的,其代码就是向关键字寄存器IWDG_KR写入0x00005555。
  • __IWDG_DISABLE_WRITE_ACCESS(__HANDLE__),使预分频寄存器IWDG_PR和重载寄存器IWDG_RLR变为不可写的,其代码就是向关键字寄存器IWDG_KR写入0x00000000。

三、独立看门狗使用示例

1、项目动作说明

        本文作者旨在介绍如何IWDG及用法。继续使用旺宝红龙开发板STM32F407ZGT6 KIT V1.0。项目的目的:  

  • 配置独立看门狗的超时为8192ms。
  • 使用RTC周期唤醒功能,唤醒周期为1s,使用一个全局变量Seconds进行秒计时。
  • 按下任何一个按键时,刷新看门狗,使全局变量Seconds归零。
  • 超过8s无按键刷新看门狗,系统将复位。 
[S2]KeyUp    = IWDG_Refresh.           LED1 ON
[S3]KeyDown  = IWDG_Refresh.           LED1 ON
[S4]KeyLeft  = IWDG_RELOAD_COUNTER.    LED2 ON
[S4]KeyRight = IWDG_RELOAD_COUNTER.    LED2 ON

        示例仍然引用KEYLED文件夹中的文件。需要参考本文作者写的其他文章:

        参考文章1:细说STM32F407单片机中断方式CAN通信_stm32f407 103 can通信-CSDN博客  https://wenchm.blog.csdn.net/article/details/144913579 

        参考文章2: 细说STM32F407单片机以DMA方式读写外部SRAM的方法_stm32外部sram可用dma吗-CSDN博客  https://wenchm.blog.csdn.net/article/details/145013118

2、工程配置

(1)DEBUG、USART6、GPIO、CodeGenrator

         与参考文章1相同。

 

(2) 时钟

        HSE和LSE均使用外部晶振。 这里,设置HCLK=168MHz,PCLK1=42MHz,PCLK2=84MHz。

(3) RTC

        开启RTC的时钟源和日历,在时钟树上设置LSE为RTC的时钟源。开启RTC的周期唤醒功能,设置唤醒时钟为1Hz信号,唤醒周期为1s。开启RTC周期唤醒中断,设置RTC的周期唤醒中断抢占优先级为1。RTC设置结果如图20-2所示。

(4)IWDG

       LSI时钟频率是32kHz,看门狗最大重载值是4095(对应0xFFF),根据预分频系数可以计算出IWDG的最长超时(timeout)。

       MCU内部的LSI时钟频率不是非常准确,例如,STM32F407的LSI频率范围是17kHz~47kHz,所以在设置刷新独立看门狗的周期时,要留出一定的余量。

        对独立看门狗IWDG的设置界面如图所示。在模式设置部分只需激活IWDG即可,参数设置部分只有两个参数。

  • IWDG counter clock prescaler,独立看门狗计数器的预分频系数,可选值为4~256。这里设置为64,因为LSI是32kHz,所以看门狗计数器的时钟信号频率是500Hz。
  • IWDG down-counter reload value,递减计数器的重载值,可输入范围是0~4095,这里设置为4095。

(5)NVIC

         开启RTC周期唤醒中断,设置RTC的周期唤醒中断抢占优先级为1。

        经过这样的设置后,递减计数器的时钟信号周期是2ms,所以独立看门狗的超时是8192ms,也就是大约8s。如果超过8s不刷新独立看门狗,系统就会复位。

3、软件设计

(1)KEYLED

         本例的项目中要使用KEYLED,其中的keyled.c和keyled.h的使用方法与参考文章2相同。

(2) main.c

/* USER CODE BEGIN Includes */
#include "keyled.h"
#include <stdio.h>
/* USER CODE END Includes */
/* USER CODE BEGIN PD */
uint8_t Seconds=0;//秒计数器
/* USER CODE END PD */
/* USER CODE BEGIN 2 */
  //IWDG初始化后就已经自动启动,且无法停止
  printf("Demo20_IWDG: Independent Watchdog\r\n");
  printf("IWDG should be refreshed in 8s.\r\n");
  printf("Press any key to refresh IWDG.\r\n");

  //显示菜单
  printf("[S2]KeyUp    = IWDG_Refresh.\r\n");
  printf("[S3]KeyDown  = IWDG_Refresh.\r\n");
  printf("[S4]KeyLeft  = IWDG_RELOAD_COUNTER.\r\n");
  printf("[S4]KeyRight = IWDG_RELOAD_COUNTER.\r\n\r\n");
  // MCU output low level LED light is on
  LED1_OFF();
  LED2_OFF();
  LED3_OFF();
  /* USER CODE END 2 */
/* USER CODE BEGIN 3 */
KEYS curKey = ScanPressedKey(KEY_WAIT_ALWAYS);
  switch(curKey)
  {
  case KEY_DOWN:
  case KEY_UP:
  {
  HAL_IWDG_Refresh(&hiwdg);//刷新IWDG
  printf("IWDG is refreshed:\r\n");
  LED1_ON();
  LED2_OFF();
  LED3_OFF();
  break;
  }

  case KEY_LEFT:
  case KEY_RIGHT:
  {
  __HAL_IWDG_RELOAD_COUNTER(&hiwdg);//刷新IWDG
  printf("IWDG is refreshed:\r\n");
  LED1_OFF();
  LED2_ON();
  LED3_OFF();
  }

  default:
  {
  LED1_OFF();
  LED2_OFF();
  LED3_OFF();
  printf("IWDG is not refreshed:\r\n");
  }
  }
Seconds = 0;//秒计数清零
HAL_Delay(500);//消除按键抖动影响
  }
  /* USER CODE END 3 */
/* USER CODE BEGIN 4 */
void HAL_RTCEx_WakeUpTimerEventCallback(RTC_HandleTypeDef *hrtc)
{
Seconds++;//秒计数值
printf("Stopwatch counting: %d\r\n",Seconds);
}

int __io_putchar(int ch)
{
HAL_UART_Transmit(&huart6,(uint8_t*)&ch,1,0xFFFF);
return ch;
}
/* USER CODE END 4 */

        在main()函数的while循环中检测按键输入,4个按键中有任何一个按下时,就会调用函数HAL_IWDG_Refresh()或宏函数_HAL_IWDG_RELOAD_COUNTER()刷新看门狗,并且使全局变量Seconds清零。这两个函数的功能是完全一样的

        文件main.c还实现了RTC周期唤醒中断的回调函数HAL_RTCEx_WakeUpTimerEventCallback(),在这个回调函数里将全局变量Seconds加1,并且在串口助手上显示。

4、运行与调试

        运行时,串口助手上会显示秒计数值,如果计数值超过4还未按下任何键,系统就会复位。如果在计数值达到4之前按任何键就会刷新看门狗,并且重新开始秒计数。

 


原文地址:https://blog.csdn.net/wenchm/article/details/145159637

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!