STM32
直播中

泡芙奶昔

11年用户 716经验值
私信 关注
[问答]

如何去启用STM32F4的窗口看门狗

STM32看门狗分为哪几种?
IWDG和WWDG有哪些相同点和不同点?
如何去启用STM32F4的窗口看门狗?

回帖(1)

李明烨

2021-8-13 17:35:10
一、介绍
STM32看门狗分为独立看门狗和窗口看门狗两种,两者使用调条件如下所示:

IWDG和WWDG两者特点如下图所示:

二、WWDG原理介绍
寄存器

控制寄存器(WWDG_CR),只有低八位有效。WDGA 位则是看门狗的激活位。T[6:0] 是7 位计数器 (MSB 到 LSB),这些位用来存储看门狗计数器的值,它每隔PCLK1 个周期递减一次。当它从 0x40 滚动到 0x3F(T6 清零)时会产生复位。
配置寄存器(WWDG_CFR),位9EWI:提前唤醒中断 ,位 8:7 计数器时钟分频器,W[6:0]窗口看门狗的上窗口
状态寄存器(WWDG_SR),这玩意仅0位有效,当计数器值达到 0x40 时此位由硬件置 1,它必须由软件通过写入 0 来清零,写入 1不起作用。如果不使能中断,在计数器的值达到 0X40的时候,此位也会被置 1。
如果激活看门狗(WWDG_CR 寄存器中的 WDGA 位置 1),则当 7 位递减计数器(T[6:0]位)从 0x40 滚动到 0x3F(T6 已清零)时会引发复位。当计数器值大于配置寄存器W[6:0]中所存储的值时,如果软件重载计数器T[6:0],则会产生复位。
应用程序在正常运行过程中必须定期地写入 WWDG_CR 寄存器以防止 MCU 发生复位。但只有当计数器值低于配置寄存器W[6:0]中的值时,才能执行此操作。存储在 WWDG_CR 寄存器T[6:0]中的值必须介于 0xFF 和 0xC0 之间:

【注】
WDGA 位则是看门狗的激活位,该位由软件置 1,以启动看门狗,并且一定要注意的是该位一旦设置,就只能在硬件复位后才能清零了。
EWI 是提前唤醒中断,即在快要产生复位的前一段时间(T[6:0]=0X40)来提醒我们,需要进行喂狗了,否则将复位!因此,我们一般用该位来设置中断,当窗口看门狗的计数器值减到 0X40 的时候,如果该位设置,并开启了中断,则会产生中断,我们可以在中断里面向 WWDG_CR 重新写入计数器的值,来达到喂狗的目的。注意这里在进入中断后,必须在不大于1个窗口看门狗计数周期的时间 (在PCLK1频率为42M且WDGTB为0的条件下,该时间为 97.52us)内重新写 WWDG_CR,否则,看门狗将产生复位!
三、WWDG时序图(重点理解)

其中:
Twwdg:WWDG 超时时间(单位为 ms),就是在写入计数器T[6:0]后,从计数器递减开始,在不重载T[6:0]的情况下,直到T[6:0]的值递减到 0x3F触发复位为止,所经过的时间
Tpclk1:1/APB1 的时钟频率(单位为 Khz)
WDGTB:WWDG 的预分频系数
T[5:0]:窗口看门狗的计数器低 6 位

【注】图中的WDGTB为3表示2^3=8,表示8分频,最小时间910us也等于每次计数器减1所需要经过的时间:T(LSB),每隔136.53us减1。最大值也等于,设置重载(喂狗)值127时(最大),一个复位周期的时间就是最大值39.91ms,也就是所能维持进入复位的最大时间。
四、代码实现
介绍要如何启用 STM32F4 的窗口看门狗
1 )使能 WWDG 时钟(IWDG 有自己独立的 32Khz 时钟,不存在使能问题。而 WWDG使用的是 PCLK1 的时钟,需要先使能时钟。)
2 )设置窗口值和分频数
3 )开启 WWDG 中断并分组
u8 WWDG_CNT=0X7F;//初始化窗口看门狗 //tr :T[6:0],计数器值 //wr :W[6:0],窗口值 //fprer:分频系数(WDGTB),仅最低2位有效 //Fwwdg=PCLK1/(4096*2^fprer)。 一般PCLK1=42Mhzvoid WWDG_Init(u8 tr,u8 wr,u32 fprer){ NVIC_InitTypeDef NVIC_InitStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG,ENABLE); //使能窗口看门狗时钟 WWDG_CNT=tr&WWDG_CNT; //初始化WWDG_CNT,设置低七位有效 WWDG_SetPrescaler(fprer); //设置分频值 WWDG_SetWindowValue(wr); //设置窗口值// WWDG_SetCounter(WWDG_CNT);//设置计数值 WWDG_Enable(WWDG_CNT); //开启看门狗,同时T[6:0]被赋初值 //中断优先级管理 NVIC_InitStructure.NVIC_IRQChannel=WWDG_IRQn;//中断窗口看门狗 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0x02;//抢占优先级为2 NVIC_InitStructure.NVIC_IRQChannelSubPriority=0x03;//子优先级为3 NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;//使能窗口看门狗中断 NVIC_Init(&NVIC_InitStructure); WWDG_ClearFlag();//清除提前唤醒中断标志位 WWDG_EnableIT();//开启提前唤醒中断}//窗口看门狗中断服务程序 void WWDG_IRQHandler(void){ WWDG_SetCounter(WWDG_CNT); //重设窗口看门狗值 WWDG_ClearFlag();//清除提前唤醒中断标志位 LED1=!LED1;}
可以看到DS1不停的闪烁,而DS0只在刚启动的时候闪一下。
举报

更多回帖

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