0%

wwdg

STM32F103窗口看门狗(Window watchdog)

1、结构框图

yV0yT0.png

  • 从RCC产生的时钟经过4096分频后进入WDG预分频器

  • WWDG_CR寄存器之T[6:0]是看门狗计数器值,预分频器每产生一个时钟减一。当从0x40变为0x3F时产生看门狗复位(T6位跳变到0)。

  • WWDG_CFR寄存器之W[6:0]是窗口值,用来与递减计数器T进行比较,W[6:0]应该小于0x80。当计数器T的值小于W时才可以重新设置WWDG_CR的T值,也就是喂狗,如下图所示:

    yV0ckV.png

    也就是说喂狗需要在0X3F与W[6:0]这个窗口之间,过早过晚都会引起复位.

    另外也可以看出,T[6:0]设置区间为0x40~0x7f.

  • WWDG_CFR之EWI位:提前唤醒中断 (Early wakeup interrupt) 此位若置’1’,则当计数器值达到40h,即产生中断。可以在中断中喂狗

  • WWDG_CFR之WDGTB位:将预分频器的时钟再次分频,该位位0-3时分别分频1、2、4、8。所以可以得到如下的计算时间公式:

    yV0gYT.png

  • 其它还包括使能位即状态位等。

2、代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include "stm32f10x_wwdg.h"

void wwdg_init(void)
{
NVIC_InitTypeDef NVIC_InitStructure;

NVIC_InitStructure.NVIC_IRQChannel = WWDG_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);

RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, ENABLE);

WWDG_SetPrescaler(WWDG_Prescaler_8);
WWDG_SetWindowValue(0x7f);
WWDG_SetCounter(0x7e);

WWDG_ClearFlag();
WWDG_Enable(0x7e);
WWDG_EnableIT();
}

void WWDG_IRQHandler(void)
{
if(WWDG_GetFlagStatus())
{
WWDG_ClearFlag();
WWDG_SetCounter(0x7e);
}
}

配置过程还是比较简单的。

3、问题

但是引出另外一个问题,即喂狗在中断中处理是否合适?

比如在一篇文章中,作者认为(原文参考末尾链接):

窗口看门狗WWDG----系统内部的故障探测器,时钟与系统相同。如果系统时钟不走了,这个狗也就失去了作用了,主要用于监视软件错误。

WWDG的中断不是用于日常喂狗的,如果用于日常喂狗动作,那WWDG的相对于IWDG,功能也就没什么特别了。WWDG的中断是给程序员最后一次喂狗的机会,一般进入这个中断时,表示你在其他地方安排的喂狗操不能凑效了,而发生这种现象时,肯定是系统有问题了,或者程序有Bug或者干扰,在这种情况下,这个中断时为了让你的程序在发生真正的看门狗复位前,有一个紧急处理的机会,如保存重要数据,或者系统刹车,说白了,就是让CPU写“遗嘱”;简单的在WWDG中断中喂狗,既没有发挥WWDG相对于IWDG的优势,又因为在中断中喂狗,而为以后的产品留下了隐患。

如果不在中断中处理,那么因为时间窗口的原因,处理起来可能会比较麻烦,就是需要每过一段时间进行一次喂狗,时间如何把控?

4、参考

https://blog.csdn.net/u012351051/article/details/50385074?utm_source=copy