HAL--独立看门狗、窗口看门狗

 

一、看门狗简介

        看门狗其实就是一个定时器,从功能上说它可以让微控制器在程序发生意外(程序进入死循环或跑飞)的时候,能重新回复到系统刚上电状态,以保障系统出问题的时候可以重启一次。说的复杂一点,看门狗就是能让程序出问题是能重新启动系统。

http://www.waveshare.net/study/data/attachment/portal/201605/03/170206cjq4hmqj3bmi408i.png

独立看门狗(IWDG)

         一个12位的递减计数器,最大值为0XFFF

         前文再续,书接上一会,上一章说到待机模式可以通过IWDG唤醒,独立看门口功能框图如下。实际上独立看门口狗就是一个递减计数器,当计时器的值减到0时,IWDG会产生一个复位信号,系统复位重新启动。为避免产生看门狗复位,则需在计数器减到0之前重载计数器,即“喂狗”。当程序出错时没有刷新计数器,计数器递减到0,系统复位重新启动,避免程序继续错误运行。

独立看门狗的定时时间并非一定非常精确,只适用于对时间精度要求比较低的场合

 

IWDG参数配置如下。IWDG的时钟为32kHz,此时设置计数器时钟为32分频,则分频后的时钟频率为1KHz.递减基础器重载值(down-counter reload value)配置为1000,即1000ms不刷新IWDG系统复位。IWDG窗口值(windows value)为默认不修改。当计数器的值大于窗口值时,如果执行重载操作,则会产生复位。(我这里随便设置的)

 

  1. int main(void)
  2. {
  3. HAL_Init();
  4. SystemClock_Config();
  5. MX_GPIO_Init();
  6. MX_USART1_UART_Init();
  7. MX_IWDG_Init();
  8. printf("test \r\n");
  9. HAL_IWDG_Init(&hiwdg);//初始化并开启iwdg F7 HAL_IWDG_Start(&hiwdg);
  10. printf("\n\r***** start main before while *****\n\r");
  11. while (1)
  12. {
  13. printf("\n\r Refreshes the IWDG !!!\n\r");
  14. HAL_IWDG_Refresh(&hiwdg);//刷新计数值,当这行被注释掉,程序会无限调用main
  15. HAL_Delay(800);
  16. }
  17. }

不喂狗

喂狗

 

 

 

一、看门狗简介

        看门狗其实就是一个定时器,从功能上说它可以让微控制器在程序发生意外(程序进入死循环或跑飞)的时候,能重新回复到系统刚上电状态,以保障系统出问题的时候可以重启一次。说的复杂一点,看门狗就是能让程序出问题是能重新启动系统。

 

独立看门狗(IWDG)

         前文再续,书接上一会,上一章说到待机模式可以通过IWDG唤醒,独立看门口功能框图如下。实际上独立看门口狗就是一个递减计数器,当计时器的值减到0时,IWDG会产生一个复位信号,系统复位重新启动。为避免产生看门狗复位,则需在计数器减到0之前重载计数器,即“喂狗”。当程序出错时没有刷新计数器,计数器递减到0,系统复位重新启动,避免程序继续错误运行。

 

 

    本章程序在串口printf工程的基础上修改,复制串口printf的工程,修改文件夹名。击STM32F746I.ioc打开STM32cubeMX的工程文件重新配置,开启独立看门狗(IWDG)。

 

 

  

 

        IWDG参数配置如下。IWDG的时钟为32kHz,此时设置计数器时钟为32分频,则分频后的时钟频率为1KHz.递减基础器重载值(down-counter reload value)配置为1000,即1000ms不刷新IWDG系统复位。IWDG窗口值(windows value)为默认不修改。当计数器的值大于窗口值时,如果执行重载操作,则会产生复位。

 

 

 

在main()函数中开启IWDG.

 

 

 

在while循环中每延时800ms刷新一次IWDG,重载计数器。

 

 

 

编译程序并下载到开发板。打开串口调试助手,设置波特率为115200,串口助手上面会显示如下信息。

 

 

当在while循环中注释掉HAL_IWDG_Refresh(&hiwdg)语句,不刷新计数器。重新编译程序时串口会输出如下信号,由于不刷新计数器,独立看门狗每1000ms复位重启一次。

 

 

再实际应用中,独立看门狗刷新操作不会再while循环中,而且也不好计算时间。一般都是通过定时器中断处理函数中刷新IWDG。

 

 

窗口看门狗(WWDG)

 

   窗口看门狗相对独立看门狗对计数器的刷新时间要求更加严格。必须在限定的时间窗口内刷新计数器。

 

 

窗口看门狗激活情况下,满足以下条件会产生复位。

    1.当递减计数器的值小于0x40时(即从0x40滚到0x3F)会产生复位。

    2.当计数器值大于窗口寄存器的值时,如果软件重载计数器,则会产生复位。

 

 

 

        从上面的时序图中可以看到,如果递减计数器的值(T[6:0])大于窗口寄存器(W[6:0])的值,重载计数器会产生复位。当递减计时器的值小于0x40时,也会产生复位。所以只能在W[6:0] ~ 0x3F之间刷新,在窗口之外重载递减计数器时复位。存储在窗口寄存器(WWDG_CR)中的值必须介于0xFF和0xC0之间。开启窗口看门狗中断时,当递减计数器的值等于0x40时触发中断。

 

 

配置WWDG计数器预分频为8,窗口寄存器的值为90,递减计数器刷新值为127。

 

WWDG时钟是挂接到APB1上,系统时钟为180MHz时,PCLK1时钟为54MHz。

则WWDG计数器的频率为:(PCLK1 (45MHz)/4096)/8) = 1648 Hz (~607 us) 

WWDG计数器刷新值为127,则超时时间为:~607 us * (127-63) = 39 ms

 

F7


 

WWDG时钟是挂接到APB1上,系统时钟为216MHz时,PCLK1时钟为45MHz。

则WWDG计数器的频率为:(PCLK1 (54MHz)/4096)/8) = 1373Hz (~728us) 

WWDG计数器刷新值为127,则超时时间为:~728 us * (127-63) ~= 47 ms

F4

 

开启窗口看门狗中断。

 

 

 

在main()函数中开启WWDG.

 

  1. int main(void)
  2. {
  3. HAL_Init();
  4. SystemClock_Config();
  5. MX_GPIO_Init();
  6. MX_USART1_UART_Init();
  7. MX_WWDG_Init();
  8. MX_NVIC_Init();
  9. printf("main \r\n");
  10. __HAL_WWDG_ENABLE_IT(&hwwdg,WWDG_IT_EWI);//开启WWDG并使能中 HAL_WWDG_EarlyWakeupCallback
  11. printf("\n\r***** start main before while*****\n\r");
  12. while (1)
  13. {
  14. printf(" Refreshes the WWDG !!!\n\r");
  15. HAL_Delay(200);
  16. }
  17. }
  18. //窗口程序的中断并不是刷新计数器 而是保存程序重要数据,不然没任何意义
  19. void HAL_WWDG_EarlyWakeupCallback(WWDG_HandleTypeDef* hwwdg)
  20. {
  21. HAL_WWDG_Refresh(hwwdg);//喂狗,当改行被注释掉则无限重启主程序
  22. }
 

 

在main.c文件后面添加WWDG中断回调函数,当递减计数器的值为0x40触发中断,中断处理函数中刷新WWDG。

 

 

编译程序并下载到开发板。打开串口调试助手,设置波特率为115200,串口助手上面会显示如下信息。

 

 

当在WWDG中断回调函数中注释掉HAL_WWDG_Refresh 语句,不刷新计数器。重新编译程序时串口会输出如下信号,由于不刷新计数器,独立看门狗每47ms复位重启一次。

 

 

 

posted @ 2023-07-21 08:50  SymPny  阅读(144)  评论(0编辑  收藏  举报