打印
[STM32F0]

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

[复制链接]
1169|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 里面的这一个例程:



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

    /* Insert 4s delay */
    HAL_Delay(4000);

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

WWDG 的结构如下:



WWDG 的设定:
  /*##-2- Init & Start WWDG peripheral ######################################*/
  /* WWDG clock counter = (PCLK1 (48MHz)/4096)/8) = 1464.8 Hz (~683 us)
     WWDG Window value = 80 means that the WWDG counter should be refreshed only
     when the counter is below 80 (and greater than 64 (63+1)) otherwise a reset will
     be generated.
     WWDG Counter value = 127, WWDG timeout = ~683 us * 64 = 43.7 ms
     In this case the refresh window is comprised between : ~683 * (127-80) = 32.1 ms and ~683 * 64 = 43.7 ms
         */
  WwdgHandle.Instance = WWDG;
  WwdgHandle.Init.Prescaler = WWDG_PRESCALER_8;
  WwdgHandle.Init.Window    = 0x50;
  WwdgHandle.Init.Counter   = 0x7F;
  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 变数:
  /* calculate delay to enter window. Add 1ms to secure round number to upper number  */
  delay = TimeoutCalculation((WwdgHandle.Init.Counter-WwdgHandle.Init.Window) + 1) + 1;
/**
  * [url=home.php?mod=space&uid=247401]@brief[/url]  Timeout calculation function.
  *         This function calculates any timeout related to
  *         WWDG with given prescaler and system clock.
  * @param  timevalue: period in term of WWDG counter cycle.
  * @retval None
  */
static uint32_t TimeoutCalculation(uint32_t timevalue)
{
  uint32_t timeoutvalue = 0;
  uint32_t pclk1 = 0;
  uint32_t wdgtb = 0;

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

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

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

  return timeoutvalue;
}

例程设定了喂狗时间为:

32.1ms + 1ms = 33.1ms

while(1) 回圈:
  /* Infinite loop */
  while (1)
  {
    /* Toggle LED2 */
    BSP_LED_Toggle(LED2);

    /* Insert calculated delay */
    HAL_Delay(delay);

    if (HAL_WWDG_Refresh(&WwdgHandle) != HAL_OK)
    {
      Error_Handler();
    }
  }

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

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

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







使用特权

评论回复
沙发
mmuuss586| | 2020-1-16 10:02 | 只看该作者
感谢分享

使用特权

评论回复
板凳
晓伍| | 2020-2-3 10:50 | 只看该作者
非常感谢楼主分享

使用特权

评论回复
地板
八层楼| | 2020-2-3 10:53 | 只看该作者
非常感谢楼主分享

使用特权

评论回复
5
观海| | 2020-2-3 10:59 | 只看该作者
非常感谢楼主分享

使用特权

评论回复
6
guanjiaer| | 2020-2-3 11:03 | 只看该作者
非常感谢楼主分享

使用特权

评论回复
7
heimaojingzhang| | 2020-2-3 11:08 | 只看该作者
非常感谢楼主分享

使用特权

评论回复
8
keaibukelian| | 2020-2-3 11:13 | 只看该作者
非常感谢楼主分享

使用特权

评论回复
9
labasi| | 2020-2-3 11:17 | 只看该作者
非常感谢楼主分享

使用特权

评论回复
10
paotangsan| | 2020-2-3 11:22 | 只看该作者
非常感谢楼主分享

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

38

主题

1177

帖子

6

粉丝