一 、前言
独立看门狗简介:
STM32F103ZET6内置两个看门狗,提供了更高的安全性、时间的精确性和使用的灵活性。两个看门狗设备(独立看门狗和窗口看门狗)可用来检测和解决由软件错误引起的故障。
独立看门狗主要性能:
- 自由运行的递减计数器
- 时钟由独立的RC振荡器提供(可在停止和待机模式下工作)
- 看门狗被激活后,则在计数器计数至0x000时产生复位
独立看门狗适用场合:
IWDG最适合应用于那些需要看门狗作为一个在主程序之外,能够完全独立工作,并且对时间精度要求较低的场合。
本次DEMO的目标:
使用STM32F103ZET6,通过按键KEY_UP来喂狗,然后通过DS0提示复位状态。
二、时钟树解析
独立看门狗(IWDG)由专用的低速时钟(LSI)驱动,即使主时钟发生故障它也仍然有效。如果独立看门狗已经由硬件选项或软件启动,LSI振荡器将被强制在打开状态,并且不能被关闭。在LSI振荡器稳定后,时钟供应给IWDG。IWDG的时钟树如下所示:
这里需要注意独立看门狗的时钟是一个内部 RC 时钟,所以并不是准确的 40Khz,而是在 30~60Khz 之间的一个可变化的时钟,只是我们在估算的时候,以 40Khz 的频率来计算,看门狗对时间的要求不是很精确,所以,时钟有些偏差,都是可以接受的。
三、寄存器介绍
与独立看门狗相关的寄存器如下所示:
寄存器 | 功能 |
---|---|
IWDG_KR | 键寄存器 |
IWDG_PR | 预分频寄存器 |
IWDG_RLR | 重装载寄存器 |
IWDG_SR | 状态寄存器 |
下面将对这些寄存器进行一一介绍。
3.1 IWDG_KR键寄存器
《STM32中文参考手册》对IWDG_KR寄存器的描述如下:
对IWDG_KR键寄存器的用法如下:
- 解锁IWDG_PR和IWDG_RLR:写入0X5555;
- 启动看门狗工作:写入0XCCCC;
- 定时喂狗:软件必须以一定的时间间隔写入0XAAAA,当计数器为0时,看门狗会复位。
3.2 IWDG_PR预分频寄存器
《STM32中文参考手册》对IWDG_PR寄存器的描述如下:
我们仅需要关注位2:0,通过改变这3位,可以设置看门狗时钟的分频系数,最低为4.最高为256。值得注意的是,只有在IWDG_SR寄存器的PVU位为0时,才能改变预分频因子。分频系数对超时时间的设置如下所示:
3.3 IWDG_RLR重装载寄存器
《STM32中文参考手册》对IWDG_RLR寄存器的描述如下:
当IWDG_KR寄存器写入0XAAAA时,重装载值寄存器的RL[11:0]中的值会被送到计数器中,然后计数器从这个值开始递减计数,值得注意的是,只有当IWDG_SR寄存器中的RVU位为0时,才能对此寄存器进行修改。
3.4 IWDG_SR状态寄存器
《STM32中文参考手册》对IWDG_SR寄存器的描述如下:
RVU位对IWDG_RLR寄存器的影响详见3.3节;
PVU位对IWDG_PR寄存器的影响详见3.2节;
四、程序设计
对IWDG程序的设计,主要分为看门狗初始化函数、喂狗函数以及轮询主函数。
4.1 看门狗初始化函数
看门狗初始化函数位于HARDWARE/wdg.c/IWDG_Init()。主要完成以下任务:
- 使用IWDG_KR寄存器对PR和RLR寄存器进行解锁。
- 使用IWDG_PR寄存器设置分频系数。
- 使用IWDG_RLR寄存器设置重装载值。
- 使用IWDG_KR寄存器写入0XAAAA,第一次喂狗。
- 使用IWDG_KR寄存器写入0XCCCC,使能看门狗。
具体代码如下所示:
//初始化独立看门狗
//prer:分频数:0~7(只有低3位有效!)
//分频因子=4*2^prer.但最大值只能是256!
//rlr:重装载寄存器值:低11位有效.
//时间计算(大概):Tout=((4*2^prer)*rlr)/40 (ms).
void IWDG_Init(u8 prer,u16 rlr)
{
IWDG->KR=0X5555;//使能对IWDG->PR和IWDG->RLR的写
while((IWDG->SR&0X1)==1); //如果SR寄存器的PVU位为1,则循环等待;
IWDG->PR=prer; //设置分频系数
while((IWDG->SR&0X2)==2); //如果SR寄存器的RVU位为1,则循环等待;
IWDG->RLR=rlr; //从加载寄存器 IWDG->RLR
IWDG->KR=0XAAAA;//reload
IWDG->KR=0XCCCC;//使能看门狗
}
4.2 喂狗函数
喂狗函数位于HARDWARE/wdg.c/IWDG_Feed()。主要是实现IWDG->KR重新写入0XAAAA,将IWDG_RLR寄存器中的值重装载。具体代码如下:
//喂独立看门狗
void IWDG_Feed(void)
{
IWDG->KR=0XAAAA;//reload
}
4.3 轮询主函数
轮询主函数位于USER/test.c/main()。主要是轮询检测KEY_UP按键是否按下,如果按下则不复位,不按下超时就复位,复位时DS0会一亮一灭。
#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "key.h"
#include "wdg.h"
int main(void)
{
Stm32_Clock_Init(9); //系统时钟设置
uart_init(72,115200); //串口初始化为115200
delay_init(72); //延时初始化
LED_Init(); //初始化与LED连接的硬件接口
KEY_Init(); //初始化与按键连接的硬件接口
delay_ms(500); //延时500ms,让人可以看到DS0灭的状态
IWDG_Init(4,625); //与分频数为64,重载值为625,溢出时间为1s
LED0=0; //点亮DS0
while(1)
{
if(KEY_Scan(0)==WKUP_PRES)//如果WK_UP按下,则喂狗
{
IWDG_Feed();
}
delay_ms(10);
};
}
五、上机实验
将程序下载入芯片,不按KEY_UP,则看门狗会超时复位,DS0会先熄灭在亮,如下图所示:
不断按下KEY_UP按键,定期喂狗,DS0就不会熄灭而常亮,如下所示:
至此完成本次DEMO!