STM32F1系列内置两个看门狗,提供了更高的安全性、时间的精确性和使用的灵活性。两个看门狗设备(独立看门狗和窗口看门狗)可用来检测和解决由软件错误引起的故障;当计数器达到给
定的超时值时,触发一个中断(仅适用于窗口型看门狗)或产生系统复位。
我们举一个例子来更好地理解看门狗。比如我们设定一个设定的看门狗触发时间128,如果我们在没有喂狗的情况下,当我们的时钟计时器数到128的时候,就会触发系统复位,整个单片机重启,重新开始计时。当再次数到128的时候,就再次重启,如此往复。于是如果单片机发生错误,无法继续进行推进到喂狗复位,在没有喂狗复位时钟的时候单片机就会重启,可能能解决相关的出错。
但是,单片机反复的重启对整个系统的危险性不亚于单片机出错或者死机。于是我们有一个“喂狗”计时时钟复位程序,来保证我们正常运行时候不发生看门狗系统复位。比如在接下来的LED循环闪烁的情况下,因为在正常运行时候,一个循环只有40ms(不考虑误差),我们在第40ms的时候就会进行喂狗,然后给看门狗计时时钟复位,使之重新开始计时。如果发生错误导致while循环没有重复,则看门狗复位程序不会触发,则会导致看门狗系统复位触发,导致整个单片机程序重启,这样一般能解决普通的软件出错。
今天我们介绍的独立看门狗(IWDG)由专用的40kHz的低速时钟驱动,即使主时钟发生故障它也仍然有效。窗口看门狗由从APB1时钟分频后得到的时钟驱动,通过可配置的时间窗口来检测应用程序非正常的过迟或过早的操作。
接下来我们来编辑我们的实验代码。
首先编辑iwdg.h头文件:
#ifndef __IWDG_H
#define __IWDG_H
#include "./SYSTEM/sys/sys.h"
void iwdg_init(uint8_t prer, uint16_t rld);
void iwdg_feed(void);
#endif
接下来我们再编译iwdg.c文件:
#include "./BSP/IWDG/iwdg.h"
IWDG_HandleTypeDef g_iwdg_handle;
void iwdg_init(uint8_t prer, uint16_t rld){
g_iwdg_handle.Instance = IWDG;
g_iwdg_handle.Init.Prescalar = prer;//分频系数
g_iwdg_handle.Init.Reload = rld;//重装载值
HAL_IWDG_Init(&g_iwdg_handle);
}
//喂狗函数
void iwdg_feed(void){
HAL_IWDG_Refresh(&g_iwdg_handle);
}
这里有两个重要参数prer分频系数和rld重装载值,是与看门狗的复位计时有关系的。我们会在之后的分析笔记中着重讲解这两个参数。
最后我们来编辑main主函数:
#include "./BSP/IWDG/iwdg.h"
#include "./BSP/LED/led.h"
#include "./BSP/DELAY/delay.h"
#include "./SYSTEM/sys/sys.h"
int main(){
HAL_Init();
sys_stm32_clock_init(RCC_PLL_MUL9);
delay_init(72);
led_init();
iwdg_init(IWDG_PRESCALAR_16 , 1250);
printf("Please feed the dog!");
while(1){
delay_ms(1000);
iwdg_feed();
printf("You have already fed the dog.");
}
}
到这里我们的实验代码就写完了。