【STM32】WWDG—窗口看门狗

在一个设定好的区间进行喂狗

与独立看门狗不同的是,独立看门狗只需要在计时到0之前喂狗。而窗口看门狗需要在设定好的区间内进行喂狗,否则进行reset。

下限

递减计数器不断的往下递减计数,当减到一个固定值 0X40时还不喂狗的话,产生复位,这个值叫窗口的下限,是固定的值,不能改变。

上限

是窗口看门狗的计数器的值在减到某一个数之前喂狗的话也会产生复位,这个值叫窗口的上限,上限值由用户独立设置。

窗口看门狗计数器的值必须在上窗口和下窗口之间才可以喂狗

功能框图

时钟源

PCLK1,PCLK1 最大是 36M,由 RCC 时钟控制器开启。

计数器时钟 PCLK -> CK时钟 -> 计数器时钟

1.计数器时钟由 CK计时器时钟经过预分频器分频得到。

2.CK 计时器时钟=PCLK1/4096,除以 4096是手册规定的,没有为什么。

3.分频系数由配置寄存器 CFR 的位 8:7 WDGTB[1:0]配置,可以是[0,1,2,3]。

所以计数器的时钟 CNT_CK=PCLK1/4096/(2^WDGTB),这就可以算出计数器减一个数的时间 T= 1/CNT_CK = Tpclk1 * 4096 * (2^WDGTB)。

计数器

1.窗口看门狗的计数器是一个递减计数器,共有 7 位,其值存在控制寄存器 CR 的位 6:0,即 T[6:0]。

2.但是由于窗口看门狗需要在窗口内喂狗,所以计数器的值只能是:0X40~0X7F 之间。

3.当递减计数器递减到 0X40的时候,还不会马上产生复位,如果使能了提前唤醒中断:CFR位 9 EWI 置1,则产生提前唤醒中断

中断服务程序里面我们就需要做最重要的工作,比如保存重要数据,或者报警等

窗口值设置和计算看门狗复位时间

详见参考手册

使用

看门狗配置

c 复制代码
/* WWDG 配置函数
* tr :递减计时器的值, 取值范围为:0x7f~0x40
* wr :窗口值,取值范围为:0x7f~0x40
* prv:预分频器值,取值可以是
* @arg WWDG_Prescaler_1: WWDG counter clock = (PCLK1/4096)/1
* @arg WWDG_Prescaler_2: WWDG counter clock = (PCLK1/4096)/2
* @arg WWDG_Prescaler_4: WWDG counter clock = (PCLK1/4096)/4
* @arg WWDG_Prescaler_8: WWDG counter clock = (PCLK1/4096)/8
*/
 void WWDG_Config(uint8_t tr, uint8_t wr, uint32_t prv)
 {
 // 开启 WWDG 时钟
 RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, ENABLE);
 
 // 设置递减计数器的值
 WWDG_SetCounter( tr );
 
 // 设置预分频器的值
 WWDG_SetPrescaler( prv );
 
 // 设置上窗口值
 WWDG_SetWindowValue( wr );
 
 // 设置计数器的值,使能 WWDG
 WWDG_Enable(WWDG_CNT);
 
 // 清除提前唤醒中断标志位
 WWDG_ClearFlag();
 // 配置 WWDG 中断优先级
 WWDG_NVIC_Config();
 // 开 WWDG 中断
 WWDG_EnableIT();
 }

中断NVIC 配置

c 复制代码
// WWDG 中断优先级初始化
static void WWDG_NVIC_Config(void)
{
NVIC_InitTypeDef NVIC_InitStructure;

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
NVIC_InitStructure.NVIC_IRQChannel = WWDG_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
 }

提前唤醒中断复位程序

这个中断函数的名称就是"提前唤醒中断"

c 复制代码
// WWDG 中断复服务程序,如果发生了此中断,表示程序已经出现了故障,
// 这是一个死前中断。在此中断服务程序中应该干最重要的事,
// 比如保存重要的数据等,这个时间具体有多长,要
// 由 WDGTB 的值决定:
// WDGTB:0 113us
// WDGTB:1 227us
// WDGTB:2 455us
// WDGTB:3 910us
void WWDG_IRQHandler(void)
 {
 // 清除中断标志位
 WWDG_ClearFlag();
  //真正使用的时候,这里应该是做最重要的事情
 }

喂狗函数

c 复制代码
 // 喂狗
 void WWDG_Feed(void)
 {
 // 喂狗,刷新递减计数器的值,设置成最大 WDG_CNT=0X7F
 WWDG_SetCounter( WWDG_CNT );
 }

使用范例

c 复制代码
int main(void)
{
uint8_t wwdg_tr, wwdg_wr;
SOFT_Delay(0X00FFFFFF);
  // 初始化 WWDG
  // 窗口值我们在初始化的时候设置成 0X5F,这个值不会改变
 WWDG_Config(0X7F, 0X5F, WWDG_Prescaler_8);
 
 wwdg_wr = WWDG->CFR & 0X7F;
  while (1) {

 //-----------------------------------------------------
 // 这部分应该写需要被 WWDG 监控的程序,这段程序运行的时间
 // 决定了窗口值应该设置成多大。
 //-----------------------------------------------------
 
 // 计时器值,初始化成最大 0X7F,当开启 WWDG 时候,这个值会不断减小
 // 当计数器的值大于窗口值时喂狗的话,会复位,当计数器减少到 0X40
 // 还没有喂狗的话就非常非常危险了,计数器再减一次到了 0X3F 时就复位
 // 所以要当计数器的值在窗口值和 0X40 之间的时候喂狗,其中 0X40 是固定的。
 wwdg_tr = WWDG->CR & 0X7F;
 
 if ( wwdg_tr < wwdg_wr ) {
 // 喂狗,重新设置计数器的值为最大 0X7F
 WWDG_Feed();
 }
 }
 }
相关推荐
CODECOLLECT1 小时前
京元 I62D Windows PDA 技术拆解:Windows 10 IoT 兼容 + 硬解码模块,如何降低工业软件迁移成本?
stm32·单片机·嵌入式硬件
BackCatK Chen2 小时前
STM32+FreeRTOS:嵌入式开发的黄金搭档,未来十年就靠它了!
stm32·单片机·嵌入式硬件·freertos·低功耗·rtdbs·工业控制
全栈游侠4 小时前
STM32F103XX 02-电源与备份寄存器
stm32·单片机·嵌入式硬件
Lsir10110_4 小时前
【Linux】中断 —— 操作系统的运行基石
linux·运维·嵌入式硬件
深圳市九鼎创展科技7 小时前
瑞芯微 RK3399 开发板 X3399 评测:高性能 ARM 平台的多面手
linux·arm开发·人工智能·单片机·嵌入式硬件·边缘计算
辰哥单片机设计7 小时前
STM32项目分享:车辆防盗报警系统
stm32·单片机·嵌入式硬件
風清掦8 小时前
【江科大STM32学习笔记-05】EXTI外部中断11
笔记·stm32·学习
小龙报8 小时前
【51单片机】从 0 到 1 玩转 51 蜂鸣器:分清有源无源,轻松驱动它奏响新年旋律
c语言·数据结构·c++·stm32·单片机·嵌入式硬件·51单片机
范纹杉想快点毕业8 小时前
嵌入式与单片机开发核心学习指南——从思维转变到第一性原理的深度实践
单片机·嵌入式硬件
Industio_触觉智能8 小时前
瑞芯微RK3566开发板规格书,详细参数配置,型号EVB3566-V1,基于RK3566核心板SOM3566邮票孔封装
嵌入式硬件·开发板·rk3568·rk3566·核心板·瑞芯微