一、简单介绍

窗口看门狗适合需要精确时序控制的场合,在一个受限的窗口期内喂狗,如果递减计数器还没有到窗口值就喂狗,会触发复位
如果一直不喂狗,也会触发复位,和之前的独立看门狗的窗口选项有点类似
需要指出的是,有些STM32单片机的独立看门狗是不具备窗口功能的,例如常见的F103C8T6


递减计数器有7位,由于计数值 >= 窗口值 >= 64,则计数器最高位亦即T6就必定是1
只要使能了窗口看门狗,WDGA就是1,右上方的与门是否输出1就取决于前一级的或门
或门的一个输入是T6,窗口期的大小就是T[5:0]这6个位,当这6位数递减至0时,最高位发生翻转,T6变成0就会触发复位
或门的另一个输入是比较器,当比较器发现计数值比窗口值还大时且有喂狗动作就输出1,也会立刻复位
二、特性

如果递减计数器还没有到窗口值就喂狗,会触发复位
如果递减计数器值小于0x40,会触发复位
具有一个早起中断,在复位前会执行这个中断
三、设置窗口值

笔者设置系统时钟为64MHz,同时也是64MHz的pclk,使用16分频,则计数频率为64MHz / 4096 / 16 = 0.976kHz,周期为1.024ms
在窗口内喂狗后计数器被赋值为T[6:0],也就是cubemx里counter的值
当计数器值介于down counter和window之间时不允许喂狗,只有计数器值介于window和0x3F之间才可以喂狗
四、cubemx配置
系统时钟

窗口看门狗

设置counter为127,window为70,则只有在第58.36~64.51ms的范围内(计数器落在[70:63])喂狗才不会复位(因为每计数一次大约1.024ms)
开启early wakeup中断

定时器
配置定时并开启中断


中断优先级

需要给看门狗中断较高的优先级
五、测试代码
主循环显示递增数,定时器喂狗次数和看门狗中断喂狗次数
cpp
/**
* @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 */
MX_GPIO_Init();
MX_DMA_Init();
MX_SPI1_Init();
MX_TIM17_Init();
// MX_WWDG_Init();
/* USER CODE BEGIN 2 */
ST7735_Init();
ST7735_ShowString(0, 0, "RESET", Font_11x18, RED, BLACK);
HAL_Delay(1000);
ST7735_Clear(BLACK);
MX_WWDG_Init();
HAL_TIM_Base_Start_IT(&htim17);
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
static uint16_t wdg = 0;
static uint16_t timer = 0;
count++;
sprintf(str, "%d ", count % 999);
ST7735_ShowString(0, 0, str, Font_11x18, GREEN, BLACK);
if (wdg != wdgcnt)
{
wdg = wdgcnt;
sprintf(str, "%d", wdgcnt);
ST7735_ShowString(0, 30, str, Font_11x18, RED, BLACK);
}
if (timer != timercnt)
{
timer = timercnt;
sprintf(str, "%d", timercnt);
ST7735_ShowString(0, 60, str, Font_11x18, BLUE, BLACK);
}
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
在看门狗中断内喂狗
cpp
void HAL_WWDG_EarlyWakeupCallback(WWDG_HandleTypeDef *hwwdg)
{
wdgcnt++;
HAL_WWDG_Refresh(hwwdg);
wdgFeedFlg = 1;
}
看门狗早起中断内进行喂狗,并将喂狗标志位置位
在1ms定时器中断内进行喂狗,判断是否已经通过看门狗中断喂过。如果喂过了,递减计数器会被重置,就不必再喂了
cpp
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
static uint8_t cnt = 0;
if (cnt == 60)
{
if (wdgFeedFlg == 0)
{
HAL_WWDG_Refresh(&hwwdg);
timercnt++;
}
else
{
wdgFeedFlg = 0;
}
cnt = 0;
}
cnt++;
}
实验证明确实如此,如果cnt等于58就喂狗也会触发复位,只有59~64才是合适的范围
六、现象
当定时器喂狗时,屏幕最底下蓝色的数字显示通过定时器喂狗的次数

当看门狗中断喂狗时,屏幕中间红色的数字显示看门狗中断喂狗次数
