1、定义:
看门狗,又叫 watchdog,从本质上来说就是一个定时器电路,一般有一个输入和一个输出,其中输入叫做喂狗,输出一般连接到另外一个部分的复位端,一般是连接到单片机。 看门狗的功能是定期的查看芯片内部的情况,一旦发生错误就向芯片发出重启信号。看门狗命令在程序的中断中拥有最高的优先级。看门狗的作用就是防止程序发生死循环,或者说程序跑飞。
在定时时间内,“看门狗”计数器是不会装满的,然后在这个时间内告诉它重新开始计数,就是把计数器清零,这个过程叫“喂狗”,这样隔一段时间喂一次狗,只要程序正常运行他就永远计不满,一旦出现死循环之类的故障,没有及时来清零计数器,就会导致装满了溢出,他就重启系统,复位。
2、CubeMX设置
STM32 的独立看门狗由内部专门的 40Khz 低速时钟驱动,即使主时钟发生故障,它也仍然 有效。
定时时间:
Tout=((4×2^prer) ×rlr) /40
其中 Tout 为看门狗溢出时间(单位为 ms);prer 为看门狗时钟预分频值(IWDG_PR 值), 范围为 0~7;rlr 为看门狗的重装载值(IWDG_RLR 的值);
比如我们设定 prer 值为 4(4 代表的是 64 分频,HAL 库中可以使用宏定义标识符 IWDG_PRESCALER_64)
当 prv 取 IWDG_ PRESCALER_64 ,rlv 取 625 时,Tout=64/40*625=1000ms。
即设置 1s 的超时溢出。
3、HAL库独立看门狗函数库讲解
看门狗初始化函数
HAL_IWDG_Init(IWDG_HandleTypeDef *hiwdg)
喂狗函数
HAL_IWDG_Refresh(IWDG_HandleTypeDef *hiwdg)
4、效果
在配置看门狗后,DS0 将常亮,如果 KEY0 按键按下,就喂狗,只要 KEY0 不停的按,看门狗就一直不会产生复位,保持 DS0 的常亮,一旦超过看门狗定溢出时间(Tout)还没按,那么将会导致程序重启,这将导致 DS0 熄灭一次。
5、代码
iwdg.c
/* Includes ------------------------------------------------------------------*/ #include "iwdg.h" IWDG_HandleTypeDef hiwdg; /* IWDG init function */ void MX_IWDG_Init(void) { /* USER CODE BEGIN IWDG_Init 0 */ /* USER CODE END IWDG_Init 0 */ /* USER CODE BEGIN IWDG_Init 1 */ /* USER CODE END IWDG_Init 1 */ hiwdg.Instance = IWDG; hiwdg.Init.Prescaler = IWDG_PRESCALER_64; hiwdg.Init.Reload = 625; if (HAL_IWDG_Init(&hiwdg) != HAL_OK) { Error_Handler(); } /* USER CODE BEGIN IWDG_Init 2 */ /* USER CODE END IWDG_Init 2 */ } /* USER CODE BEGIN 1 */ //喂独立看门狗 void IWDG_Feed(void) { HAL_IWDG_Refresh(&hiwdg); //喂狗 } /* USER CODE END 1 */
main.c
#include "main.h" #include "iwdg.h" #include "gpio.h" /* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ /* USER CODE END Includes */ /* Private typedef -----------------------------------------------------------*/ /* USER CODE BEGIN PTD */ #define u8 unsigned char #define KEY0 HAL_GPIO_ReadPin(GPIOE,GPIO_PIN_4) // 按键 PE4 #define LED0 HAL_GPIO_WritePin(GPIOB,GPIO_PIN_5,GPIO_PIN_RESET); //LED0 亮 /* USER CODE END PTD */ /* Private define ------------------------------------------------------------*/ /* USER CODE BEGIN PD */ /* USER CODE END PD */ /* Private macro -------------------------------------------------------------*/ /* USER CODE BEGIN PM */ /* USER CODE END PM */ /* Private variables ---------------------------------------------------------*/ /* USER CODE BEGIN PV */ /* USER CODE END PV */ /* Private function prototypes -----------------------------------------------*/ void SystemClock_Config(void); /* USER CODE BEGIN PFP */ /* USER CODE END PFP */ /* Private user code ---------------------------------------------------------*/ /* USER CODE BEGIN 0 */ u8 KEY_Scan2(void) { static u8 key_up=1; if(key_up && KEY0==0) { HAL_Delay(10);//延时,防抖 key_up=0;//标记这次key已经按下 if(KEY0==0) { return 1; } }else if(KEY0!=0) key_up=1; return 0; } /* USER CODE END 0 */ /** * @brief The application entry point. * @retval int */ int main(void) { /* USER CODE BEGIN 1 */ /* USER CODE END 1 */ /* MCU Configuration--------------------------------------------------------*/ /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ HAL_Init(); /* USER CODE BEGIN Init */ /* USER CODE END Init */ /* Configure the system clock */ SystemClock_Config(); /* USER CODE BEGIN SysInit */ /* USER CODE END SysInit */
/* Initialize all configured peripherals */ HAL_Delay(100);//延时 100ms 再初始化看门狗,LED0 的变化"可见" MX_GPIO_Init(); MX_IWDG_Init(); /* USER CODE BEGIN 2 */ LED0; /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { if(KEY_Scan2()==1) //如果 KEY0 按下,喂狗 { IWDG_Feed(); //喂狗 } /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ } /* USER CODE END 3 */ }
6、下载认证
在编译成功之后,我们就可以下载代码到精英 STM32 V1 开发板上,实际验证一下,我们 的程序是否正确。下载代码后,可以看到 DS0 不停的闪烁,证明程序在不停的复位,否则只会 DS0 常亮。这时我们试试不停的按 KE0 按键,可以看到 DS0 就常亮了,不会再闪烁。
标签:BEGIN,IWDG,END,看门狗,STM32,CODE,USER From: https://www.cnblogs.com/CC-C/p/17020045.html