[STM32F0] 学习笔记+STM32F0系列的STM32Cube固件例程 WWDG

[复制链接]
1524|9
 楼主| slotg 发表于 2020-1-1 22:44 | 显示全部楼层 |阅读模式
本帖最后由 slotg 于 2020-1-1 22:49 编辑

学习笔记+适用于STM32F0系列的STM32Cube固件例程
学习笔记+STM32F0系列的STM32Cube固件例程 DMA
学习笔记+STM32F0系列的STM32Cube固件例程 IWDG


STM32F0 的另一个看门狗就是 WWDG,也就是 Window watchdog 窗口看门狗,与 IWDG 不同的地方是 IWDG 使用内部 LSI 做为时钟驱动,而 WWDG 是使用 PCLK 时钟驱动。 WWDG 窗口看门狗的计数器下限值是固定在 0x40,上限值是由使用者设定,低于下限值的时间喂狗不行,超过上限值的时间喂狗也不行。

WWDG_Example

在固件库 Projects\STM32F030R8-Nucleo\Examples\WWDG\WWDG_Example 里面的这一个例程:

P01.JPG

程序的基本架构跟前面的 IWDG 例程类似,main() 开始的地方也是有一个判断语句判断程序的复位原因是否是因为 WWDG 所产生的?是的话点亮 LD2 4秒钟。
  1.   /*##-1- Check if the system has resumed from WWDG reset ####################*/
  2.   if (__HAL_RCC_GET_FLAG(RCC_FLAG_WWDGRST) != RESET)
  3.   {
  4.     /* WWDGRST flag set: Turn LED2 on */
  5.     BSP_LED_On(LED2);

  6.     /* Insert 4s delay */
  7.     HAL_Delay(4000);

  8.     /* Prior to clear WWDGRST flag: Turn LED2 off */
  9.     BSP_LED_Off(LED2);
  10.   }

WWDG 的结构如下:

P02.JPG

WWDG 的设定:
  1.   /*##-2- Init & Start WWDG peripheral ######################################*/
  2.   /* WWDG clock counter = (PCLK1 (48MHz)/4096)/8) = 1464.8 Hz (~683 us)
  3.      WWDG Window value = 80 means that the WWDG counter should be refreshed only
  4.      when the counter is below 80 (and greater than 64 (63+1)) otherwise a reset will
  5.      be generated.
  6.      WWDG Counter value = 127, WWDG timeout = ~683 us * 64 = 43.7 ms
  7.      In this case the refresh window is comprised between : ~683 * (127-80) = 32.1 ms and ~683 * 64 = 43.7 ms
  8.          */
  9.   WwdgHandle.Instance = WWDG;
  10.   WwdgHandle.Init.Prescaler = WWDG_PRESCALER_8;
  11.   WwdgHandle.Init.Window    = 0x50;
  12.   WwdgHandle.Init.Counter   = 0x7F;
  13.   WwdgHandle.Init.EWIMode   = WWDG_EWI_DISABLE;

PCLK 的频率设定在 48MHz,经过一个 4096 除频之后再进入 WWDG 的预除器,程序中设定预除器为 8,所以 WWDG 计数器的输入频率为:

48MHz / 4096 = 11718.75Hz
11718.75Hz / 8 = 1464.84Hz --> 约 683us

WWDG 从 0x7F 开始往下计数,计数到 0x50 时进入 WWDG 可喂狗的下限值,这时间为:

127 - 80 = 47
47 x 683us = 32101us --> 约 32.1ms

WWDG 窗口的上限值是 0x40,这是可喂狗时间的最长时间,这时间为:

127 - 64 = 63
(63+1) x 683us = 43712us --> 约 43.7ms

也就是喂狗时间必须是在 32.1ms ~ 43.7ms 之间。

例程中设定了喂狗周期的 delay 变数:
  1.   /* calculate delay to enter window. Add 1ms to secure round number to upper number  */
  2.   delay = TimeoutCalculation((WwdgHandle.Init.Counter-WwdgHandle.Init.Window) + 1) + 1;
  1. /**
  2.   * [url=home.php?mod=space&uid=247401]@brief[/url]  Timeout calculation function.
  3.   *         This function calculates any timeout related to
  4.   *         WWDG with given prescaler and system clock.
  5.   * @param  timevalue: period in term of WWDG counter cycle.
  6.   * @retval None
  7.   */
  8. static uint32_t TimeoutCalculation(uint32_t timevalue)
  9. {
  10.   uint32_t timeoutvalue = 0;
  11.   uint32_t pclk1 = 0;
  12.   uint32_t wdgtb = 0;

  13.   /* considering APB divider is still 1, use HCLK value */
  14.   pclk1 = HAL_RCC_GetPCLK1Freq();

  15.   /* get prescaler */
  16.   wdgtb = (1 << ((WwdgHandle.Init.Prescaler) >> 7)); /* 2^WDGTB[1:0] */

  17.   /* calculate timeout */
  18.   timeoutvalue = ((4096 * wdgtb * timevalue) / (pclk1 / 1000));

  19.   return timeoutvalue;
  20. }

例程设定了喂狗时间为:

32.1ms + 1ms = 33.1ms

while(1) 回圈:
  1.   /* Infinite loop */
  2.   while (1)
  3.   {
  4.     /* Toggle LED2 */
  5.     BSP_LED_Toggle(LED2);

  6.     /* Insert calculated delay */
  7.     HAL_Delay(delay);

  8.     if (HAL_WWDG_Refresh(&WwdgHandle) != HAL_OK)
  9.     {
  10.       Error_Handler();
  11.     }
  12.   }

因此程序运行时可以看到板载 LD2 快速闪烁。当我们按下使用者键时会产生按键中断,中断函数里对地址 0xA0003000 写入数据 0xFF,由于这个地址的写入动作是无效的因此会产生一个 Hardfault 错误事件。
  1. void EXTI4_15_IRQHandler(void)
  2. {
  3.   /* As the following address is invalid (not mapped), a Hardfault exception
  4.   will be generated with an infinite loop and when the WWDG counter falls to 63
  5.   the WWDG reset occurs */
  6.   *(__IO uint32_t *) 0xA0003000 = 0xFF;
  7. }

在 Hardfault 响应函数中我们放了一个无限回圈让程序回不去。
  1. void HardFault_Handler(void)
  2. {
  3.   /* Go to infinite loop when Hard Fault exception occurs */
  4.   while (1)
  5.   {
  6.   }
  7. }

由于程序回不去了因此主回圈就没有办法喂狗,所以 WWDG 会复位 MCU,重启后 LD2 点亮 4秒钟后再快速闪烁。







mmuuss586 发表于 2020-1-16 10:02 | 显示全部楼层
感谢分享
晓伍 发表于 2020-2-3 10:50 | 显示全部楼层
非常感谢楼主分享
八层楼 发表于 2020-2-3 10:53 | 显示全部楼层
非常感谢楼主分享
观海 发表于 2020-2-3 10:59 | 显示全部楼层
非常感谢楼主分享
guanjiaer 发表于 2020-2-3 11:03 | 显示全部楼层
非常感谢楼主分享
heimaojingzhang 发表于 2020-2-3 11:08 | 显示全部楼层
非常感谢楼主分享
keaibukelian 发表于 2020-2-3 11:13 | 显示全部楼层
非常感谢楼主分享
labasi 发表于 2020-2-3 11:17 | 显示全部楼层
非常感谢楼主分享
paotangsan 发表于 2020-2-3 11:22 | 显示全部楼层
非常感谢楼主分享
您需要登录后才可以回帖 登录 | 注册

本版积分规则

38

主题

1177

帖子

6

粉丝
快速回复 在线客服 返回列表 返回顶部