简介
首先简单介绍一下看门狗的作用。
看门狗用来防止系统在运行过程中遇到的各种异常情况,而导致程序不能继续运行。可以理解为,看门狗是一种可以挽救系统进入异常进而系统无法继续工作的保障。当系统启动看门狗功能后,计数器开始计数,在计数器完成计数的时刻之前,系统程序必须“喂狗”,使得让看门狗知道系统依然“活着”。如果到了指定时间,系统没有去“喂狗”,则看门狗产生一个复位信号,系统从 Reset 重新运行。
从系统实现的角度上来看,看门狗其实就是一个计数器而已,当计数的个数达到终点时刻,产生复位信号。若计数未到达终点,软件干涉,进行喂狗的行为,则计数器重新计数,不会产生复位。
STM32 拥有两种类型的看门狗:独立看门狗(IWDG)和窗口看门狗(WWDG)。
这一篇主要介绍独立看门狗的用法 IWDG。
时钟
STM32 独立看门狗时钟由 LSI 低频 RC 震荡提供。LSI时钟频率大约40kHz(在30kHz和60kHz之间)。所以,如果要使用这个玩意的话,是不是应该像其他外设一样,需要手动先开启 LSI 时钟呢?
答案是,可以这样做,也可以不!
因为:
可以看到,LSI 将会被强制开启,故,只要启动开门狗,则 LSI 将会强制被开启,这就意味着,我们不需要手动去开启 LSI 时钟。
工作原理
IWDG最适合应用于那些需要看门狗作为一个在主程序之外,能够完全独立工作,并且对时间精度要求较低的场合。
- IWDG 含自由运行的递减计数器
- 时钟由独立的RC振荡器提供(可在停止和待机模式下工作)
- 看门狗被激活后,则在计数器计数至0x000时产生复位
结构框图如图所示:
主要包含的一个:
IWDG_PR 的预分频器,将来自 LSI 的 40kHZ 的时钟进行分频处理。
IWDG_RLR 重装载寄存器,即计数器的递减起始的值
IWDG_KR 键寄存器负责执行命令:
1. 写入0xAAAA 代表喂狗
2. 写入0x5555表示允许访问IWDG_PR和IWDG_RLR寄存器
3. 写入0xCCCC,启动看门狗工作
配置过程
所以对 IWDG 的使用和配置过程如下所示:
1. 开启 LSI 时钟,并等待其有效
2. 写 0x5555 到 IWDG_KR,允许访问其他寄存器。
3. 写预分频器的值为 4(即 64分频)
4. 配置计时器的值为 625 (产生 1s 的 Timeout)
5. 写入 0xAAAA 到 IWDG_KR 避免产生复位
6. 写入 0xCCCC 到 IWDG_KR,开启看门狗功能。
注意:使用往 IWDG_KR 写入 0xAAAA 来实现喂狗功能,若不定期喂狗,则产生复位中断
代码
/*
***************************************************************
******************* IWDG Function Defination *******************
***************************************************************
*/
#define SK_IWDG_PER 4 // 64 Prescaler divider to 625
#define SK_IWDG_CNT 625 // 1s timeout
void SK_IWDGInit(uint16_t prer, uint16_t wdg_value)
{
// First Open LSI Clock for IWDG
RCC_LSICmd(ENABLE);
while (RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET);
// If use IWDG, LSI will be opened force
IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);
// Set Prescaler
IWDG_SetPrescaler(prer);
// Set reload value
IWDG_SetReload(wdg_value);
// Set 0xAAAA To make sure not go into reset
IWDG_ReloadCounter();
// Enable WDG
IWDG_Enable();
}
void SK_IWDGFeed(void)
{
IWDG_ReloadCounter();
}