title: 独立看门狗
date: 2021-12-14 10:11:44
tags: 嵌入式
引言
“独立看门狗”这个词对于我来说并不是太陌生,本科那会在学嵌入式的时候很有幸一道大题目专门出过这样一道题目。当时对这个部分的认知就是独立看门狗是用来防止程序跑飞的东西,内部有专门的配置来进行“喂狗”,如果程序跑飞之后便会对系统进行复位。当然具体怎么配置老师没有详细地讲述过,下面我将对该独立看门狗进行一次概略的总述。
看门狗简述
在单片机构成的微型计算机系统中,由于单片机的工作常常会受到来自外界电磁场的干扰,造成程序的跑飞,而陷入死循环,程序的正常运行被打断,由单片机控制的系统无法继续工作,会造成整个系统陷入停滞状态,发生不可预料的后果,所以处于对单片机运行状态进行实时监测的考虑,便产生了一种专门用于监测单片机程序运行状态的模块或者芯片,俗称为“看门狗”。
STM32内置两个看门狗:窗口看门狗和独立看门狗。这里主要叙述独立看门狗:当计数器达到给定的超时值时,触发一个中断(仅适用窗口看门狗)或者产生系统复位。
独立看门狗(IWDG)由专用的低速时钟(LSI)驱动,即使主时钟发生故障它依旧有效。**独立看门狗适用于需要看门狗作为一个在主程序之外,能够完全独立工作,并且对时间精度要求较低的场合。**窗口看门狗由APB1时钟分频后得到时钟驱动。通过配置的时间窗口来检测应用程序非正常的过迟或过早操作。窗口看门狗最适合那些要求看门狗在精确计时窗口起作用的程序。
独立看门狗
在键值寄存器(IWDG_KR)中写入0xCCCC,开始启用独立看门狗。此时计数器开始从其复位值0xFFF递减,当计数器值计数到0x000时会产生一个复位信号(IWDG_RESET)无论何时,只要在键值寄存器IWDG_KR中写入0xAAAA(即喂狗),自动重装载寄存器IWDG_RLR的值就会重新加载到计数器,从而避免看门狗复位,如果程序异常就无法正常喂狗,从而系统就复位。独立看门狗的框图如下图所示:
从图中我们易知LSI经过8位预分频。状态寄存器IWDG_SR只有两位,位1是RVU看门狗计数器重装载值更新,重装值只有在RVU位被清“0”后才可更新;位0是PVU看门狗预分频值更新,此位由硬件置“1”用来表示预分频值的更新正在进行中,预分频值只有在PVU位被清“0”后才可以更新。重装载寄存器只有键寄存器写入0xAAAA时重装载值会被传送到计数器中,随后计数器从这个值开始递减计数。健寄存器写入0x5555表示允许访问IWDG_PR和IWDG_RLR寄存器写入0xCCCC,启动看门狗工作。
看门狗超时时间
对于独立看门狗超时时间可以参照下表所示:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SxT3hxqz-1646289204059)(https://cdn.jsdelivr.net/gh/wangfei-tech/IU/img/%E7%9C%8B%E9%97%A8%E7%8B%97%E8%B6%85%E6%97%B6%E6%97%B6%E9%97%B4.png)]
我们可以从上表中看出在不同的预分频系数下有不同的超时最短时间和最长时间,我们在实际案例中配置位64分频。对于超时时间的计算可以参照下述公式进行计算:Tout=((4×2^prer) ×rlr) /40 (M3)根据前面的介绍我们也能很容易的清楚需要设置两个参数来达到设置超时时间。prer为预分频的PR位,rlr为重装载值。我们在知道想要的超时时间和预分频系数之后就可以计算出重装载值。当然这里只是空谈归于怎么设置需要到程序中进行配置。
IWDG具体配置步骤
首先我们要明确在库函数版本中stm32f10x_iwdg.h中提供给我们的几个库函数:
void IWDG_WriteAccessCmd(uint16_t IWDG_WriteAccess);//取消写保护:0x5555使能
void IWDG_SetPrescaler(uint8_t IWDG_Prescaler);//设置预分频系数:写PR
void IWDG_SetReload(uint16_t Reload);//设置重装载值:写RLR
void IWDG_ReloadCounter(void);//喂狗:写0xAAAA到KR
void IWDG_Enable(void);//使能看门狗:写0xCCCC到KR
FlagStatus IWDG_GetFlagStatus(uint16_t IWDG_FLAG);//状态:重装载/预分频 更新
具体的配置步骤如下所示:
①取消寄存器写保护:IWDG_WriteAccessCmd();
②设置独立看门狗的预分频系数,确定时钟:IWDG_SetPrescaler();
③设置看门狗重装载值,确定溢出时间:IWDG_SetReload();
④使能看门狗IWDG_Enable();
⑤应用程序喂狗:IWDG_ReloadCounter();
溢出时间计算:Tout=((4×2^prer) ×rlr) /40 (M3)
我们定义iwdg.h头文件声明需要的iwdg初始化函数,该初始化参数入口参数为两个参数分为prer和rlr,在源文件中我们进行具体上述步骤进行配置,①中我们IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);在②中是我们在头文件中入口参数prer③中是入口参数rlr④中为看门狗使能⑤中为应用程序进行喂狗。上述过程就完成了看门狗的初始化。
我们在main.c中进行具体的程序编写,首先是初始化外设然后再初始化IWDG,我们想要的超时时间为1s,故需要配置rlr。rlr是需要计算出来的,怎么计算前面已经具体写过流程了。我们只需要再规定的时间内进行“喂狗”就可以了。