STM32
直播中

陈杰

7年用户 1384经验值
私信 关注
[问答]

怎样去配置STM32F103独立看门狗( IWDG)

什么是独立看门狗( IWDG)?
独立看门狗( IWDG)的结构是由哪些部分组成的?
怎样去配置独立看门狗( IWDG)?

回帖(1)

曹雪琰

2021-8-18 17:10:29
一、使用背景
它的主要功能是在发生软件故障时, 将单片机复位重启。
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(); //重新加载重装载寄存器的值至计数器}
举报

更多回帖

发帖
×
20
完善资料,
赚取积分