STM32之独立看门狗

一、使用背景

它的主要功能是在发生软件故障时, 将单片机复位重启

STM32F103 内置独立看门狗和窗口看门狗两类看门狗。

二、独立看门狗介绍

独立看门狗( IWDG) 顾名思义它是独立运行的, 由专用的低速时钟 LSI 驱动。 优点是当系统主时钟发生故障或停止运行时它仍然有效, 不受程序运行及中断的影响, 缺点是 LSI精度受环境影响较大, 精度不高, 因此 IWDG 适用于对时间精度要求不高的场合。

IWDG 是一个 12 位的递减计数器, 首先根据所需要设定的时间计算出初值, 然后将初值写入到重装载寄存器中, 启动 IWDG 后开始倒计时, 当计数器计到 0 时会产生一个复位信号, 引起系统复位。 因此按照正常逻辑时序运行程序的话, 必须在计数器计到 0 之前喂狗,IWDG 结构如图所示。

在这里插入图片描述

1、LSI时钟

LSI 的时钟主频为 40KHz, 由于 LSI 时钟本身不准确, 受环境影响会发声一定的漂移现象, 其频率会在 30KHz 到 60KHz 之间变化, 因此喂狗时应该给出一定的余量。

2、键寄存器( IWDG_KR)

键寄存器是一个只写的控制寄存器, 向其写入命令字可以实现相应的配置功能。 由于 IWDG 能够导致系统复位, 为了防止意外复位, IWDG 的预分频寄存器和重装载寄存器具有写保护功能, 防止寄存器数据被随意篡改。 要修改这两个寄存器的值, 必须先向键寄存器中写入 0x5555, 取消写保护功能,除此之外间寄存器控制 IWDG 的重装载使能和启动 IWDG 功能, 键寄存器控制字命令如下表所示。

在这里插入图片描述

3、预分频寄存器( IWDG_PR)

定时器的预分频系数可以设置为 0~2N( N 为预分频寄存器的位数) 中的任意一个数,而 IWDG 的预分频寄存器稍有不同, IWDG_PR 寄存器的有效位只有 3 位, 设置参数对应的分频系数如下表所示。

在这里插入图片描述

写入到 IWDG_PR 寄存器的参数会自动转化为相应的预分频系数传递到 IWDG 的 8 位预分频器中。

4、重装载寄存器( IWDG_RLR)

重装载寄存器是一个 12 位的寄存器, 用于存储用户设定的计数值,其设置范围为 0~4095。

IWDG 的计时时间为: ( 预分频值/时钟频率)× 重装载值

其所能设定的最大复位时间为 : (1/40KHz)× 256× 4096= 26.2s 左右。

5、状态寄存器( IWDG_SR)

状态寄存器只有最低两位 RVU 和 PVU 位有效, 分别表示重装载值和预分频值更新状态, 当相应寄存器正在进行数据更新时, 对应的状态位由硬件置“ 1”, 更新完毕后由硬件清“ 0”, 只有当 RVU 和 PVU 为 0 时, 表示重装载值和预分频值已经更新完毕。

三、独立看门狗配置
1、 IWDG 配置流程

通常应用独立看门狗时, 首先估算程序执行一个整周期循环的时间, 比如 20ms, 程序执行完毕后执行“ 喂狗” 操作, 由于 LSI 精度不高, 因此要留有一定余量。 假设设定 IWDG溢出时间是 25ms, 如果经过 25ms 后还未喂狗, 说明程序出现故障, IWDG 会触发系统复位,程序重新执行。

已知定时时间为 25ms, LSI 时钟频率为 40KHz,

根据公式: 定时时间( s) =( 预分频数/时钟频率) *重装载值,

可以得出 重装载值*预分频值=1000, 如果设置 4 分频, 则重装载值为 250, 实际写入到重装载寄存器的值要减 1 即为 249。

IWDG 配置流程如下:
1、 取消 IWDG 寄存器写保护
2、 设置 IWDG 预分频系数
3、 设置 IWDG 重装载值
4、 重载计数器的初值
5、 启动看门狗

2、代码
#include "wdg.h"

/* 独立看门狗初始化;Prescaler-预分频值(范围 0~7),Reload-重装载值(范围 0~4095) */
//时间计算:Tout=((4*2^Prescaler)*Reload)/40 (ms)
void IwdgInit(u16 Prescaler, u16 Reload)
{
	//使能能对 IWDG_PR 和 IWDG_RLR 寄存器的写操作
	IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);
	IWDG_SetPrescaler(Prescaler);//设置 IWDG 预分频值
	IWDG_SetReload(Reload-1); //设置 IWDG 重装载值
	IWDG_ReloadCounter(); //将 IWDG 重装载寄存器的值写入到 IWDG 计数器
	IWDG_Enable(); //使能 IWDG
} 

* 独立看门狗喂狗 */
void FeedIwdg(void)
{
	IWDG_ReloadCounter(); //重新加载重装载寄存器的值至计数器
}
发布了653 篇原创文章 · 获赞 1016 · 访问量 73万+

猜你喜欢

转载自blog.csdn.net/ReCclay/article/details/104010323
今日推荐