打印
[STM32F1]

STM32基础篇————窗口看门狗

[复制链接]
1665|20
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 aizaixiyuanqian 于 2018-1-7 12:39 编辑

这次实验,介绍如何使用 STM32 的另外一个看门狗,窗口看门狗(以下简称 WWDG)。 我们将利用窗口看门狗的中断功能来喂狗,通过 printf 打印输出。本次实验目标:
1、了解 STM32 的内部看门狗。
2、学会配置看门狗。


沙发
aizaixiyuanqian|  楼主 | 2018-1-7 12:40 | 只看该作者
STM32  窗口 看门狗简介
窗口看门狗( WWDG)通常被用来监测由外部干扰或不可预见的逻辑条件造成的应用程序背离正常的运行序列而产生的软件故障。除非递减计数器的值在 T6 位 ( WWDG->CR 的第六位)变成 0 前被刷新,看门狗电路在达到预置的时间周期时,会产生一个 MCU 复位。在递减计数器达到窗口配置寄存器(WWDG->CFR)数值之前,如果 7 位的递减计数器数值(在控制寄存器中)被刷新, 那么也将产生一个 MCU 复位。这表明递减计数器需要在一个有限的时间窗口中被刷新。 他们的关系可以用图来说明:


使用特权

评论回复
板凳
aizaixiyuanqian|  楼主 | 2018-1-7 12:41 | 只看该作者
T[6:0]就是 WWDG_CR 的低七位, W[6:0]即是 WWDG->CFR 的低七位。T[6:0]就是窗口看门狗的计数器,而 W[6:0]则是窗口看门狗的上窗口,下窗口值是固定的( 0X40)。当窗口看门狗的计数器在上窗口值之外被刷新,或者低于下窗口值都会产生复位。上窗口值( W[6:0]) 是由用户自己设定的,根据实际要求来设计窗口值,但是一定要确保窗口值大于 0X40,否则窗口就不存在了。窗口看门狗的超时公式如下:Twwdg=(4096×2^WDGTB×(T[5:0]+1)) /Fpclk1;其中:Twwdg: WWDG 超时时间(单位为 ms)Fpclk1: APB1 的时钟频率(单位为 Khz)WDGTB: WWDG 的预分频系数T[5:0]:窗口看门狗的计数器低 6 位

使用特权

评论回复
地板
aizaixiyuanqian|  楼主 | 2018-1-7 12:42 | 只看该作者
根据上面的公式,假设 Fpclk1=36Mhz,那么可以得到最小-最大超时时间表如表所示:

使用特权

评论回复
5
aizaixiyuanqian|  楼主 | 2018-1-7 12:42 | 只看该作者
可以看出,这里我们的 WWDG_CR 只有低八位有效, T[6: 0]用来存储看门狗的计数器值,随时更新的,每个看窗口看门狗计数周期( 4096×2^ WDGTB)减 1。当该计数器的值从 0X40变为 0X3F 的时候,将产生看门狗复位。WDGA 位则是看门狗的激活位,该位由软件置 1,以启动看门狗,并且一定要注意的是该位一旦设置,就只能在硬件复位后才能清零了。

使用特权

评论回复
6
aizaixiyuanqian|  楼主 | 2018-1-7 12:43 | 只看该作者
窗口看门狗的第二个寄存器是配置寄存器( WWDG_CFR),该寄存器的各位及其描述如图所示:

使用特权

评论回复
7
aizaixiyuanqian|  楼主 | 2018-1-7 12:44 | 只看该作者
该位中的 EWI 是提前唤醒中断,也就是在快要产生复位的前一段时间( T[6:0]=0X40) 来提醒我们,需要进行喂狗了,否则将复位!因此,我们一般用该位来设置中断,当窗口看门狗的计数器值减到 0X40 的时候,如果该位设置, 并开启了中断,则会产生中断,我们可以在中断里面向 WWDG_CR 重新写入计数器的值,来达到喂狗的目的。注意这里在进入中断后, 必须在不大于 1 个窗口看门狗计数周期的时间( 在 PCLK1 频率为 36M 且 WDGTB 为0 的条件下,该时间为 113us)内重新写 WWDG_CR,否则,看门狗将产生复位!

使用特权

评论回复
8
aizaixiyuanqian|  楼主 | 2018-1-7 12:44 | 只看该作者
最后我们要介绍的是状态寄存器( WWDG_SR),该寄存器用来记录当前是否有提前唤醒的标志。该寄存器仅有位 0 有效,其他都是保留位。当计数器值达到 40h 时,此位由硬件置 1。它必须通过软件写 0 来清除。对此位写 1 无效。 即使中断未被使能, 在计数器的值达到 0X40 的时候, 此位也会被置 1。

使用特权

评论回复
9
aizaixiyuanqian|  楼主 | 2018-1-7 12:44 | 只看该作者
独立看门狗 的操作步骤
在介绍完了窗口看门狗的寄存器之后,我们介绍要如何启用 STM32 的窗口看门狗。 这里我们介绍库函数中用中断的方式来喂狗的方法,窗口看门狗库函数相关源码和定义分布在文件 stm32f10x_wwdg.c 文件和头文件 stm32f10x_wwdg.h 中。步骤如下:

使用特权

评论回复
10
aizaixiyuanqian|  楼主 | 2018-1-7 12:45 | 只看该作者
1 )  使能 WWDG  时钟
WWDG 不同于 IWDG, IWDG 有自己独立的 40Khz 时钟,不存在使能问题。而 WWDG使用的是 PCLK1 的时钟,需要先使能时钟。 方法是:RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, ENABLE); // WWDG 时钟使能

使用特权

评论回复
11
aizaixiyuanqian|  楼主 | 2018-1-7 12:45 | 只看该作者
2 )  设置窗口值和分频数
设置窗口值的函数是:void WWDG_SetWindowValue(uint8_t WindowValue);这个函数就一个入口参数为窗口值,很容易理解。设置分频数的函数是:void WWDG_SetPrescaler(uint32_t WWDG_Prescaler);这个函数同样只有一个入口参数就是分频值。

使用特权

评论回复
12
aizaixiyuanqian|  楼主 | 2018-1-7 12:46 | 只看该作者
3 )  开启 W W WDG  中断并分组
开启 WWDG 中断的函数为:WWDG_EnableIT(); //开启窗口看门狗中断接下来是进行中断优先级配置,这里就不重复了,使用 NVIC_Init()函数即可。

使用特权

评论回复
13
aizaixiyuanqian|  楼主 | 2018-1-7 12:47 | 只看该作者
4)  设置计数器初始值并使能看门狗
这一步在库函数里面是通过一个函数实现的:void WWDG_Enable(uint8_t Counter);该函数既设置了计数器初始值,同时使能了窗口看门狗。

使用特权

评论回复
14
aizaixiyuanqian|  楼主 | 2018-1-7 12:47 | 只看该作者
5)  编写中断服务函数
在最后还是要编写窗口看门狗的中断服务函数,通过该函数来喂狗,喂狗要快,否则当窗口看门狗计数器值减到 0X3F 的时候,就会引起软复位了。在中断服务函数里面也要将状态寄存器的 EWIF 位清空。完成了以上 5 个步骤之后,我们就可以使用 STM32 的窗口看门狗了。这一章的实验,我们将通过 printf 打印输出喂狗,每一秒后在 while 内输出普中科技欢迎您!,如果系统被复位了将会打印我们公司的网址 。

使用特权

评论回复
15
aizaixiyuanqian|  楼主 | 2018-1-7 12:48 | 只看该作者
窗口看门狗配置:
void wwdg_init()
{
NVIC_InitTypeDef NVIC_InitStructure;  //中断结构体定义
RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, ENABLE); // WWDG 时钟使能
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);
WWDG_SetPrescaler(WWDG_Prescaler_8);//设置 WWDG 预分频数值
WWDG_SetWindowValue(0x5F);//窗口上边界数值
WWDG_Enable(0x7F);//使能窗口看门狗
WWDG_ClearFlag(); //清除提前唤醒中断标志
WWDG_EnableIT();//开启窗口看门狗中断
}

使用特权

评论回复
16
aizaixiyuanqian|  楼主 | 2018-1-7 12:48 | 只看该作者
窗口看门狗中断程序
void WWDG_IRQHandler(void)  //窗口看门狗中断程序
{
WWDG_SetCounter(0x7F);  //喂狗
WWDG_ClearFlag();
printf("喂狗\r\n");
}

使用特权

评论回复
17
aizaixiyuanqian|  楼主 | 2018-1-7 12:49 | 只看该作者
例程主程序
int main()
{
printf_init();  //printf 初始化
wwdg_init(); //窗口看门狗初始化配置
while(1)
{
delay_ms(1000);
}
}

使用特权

评论回复
18
aizaixiyuanqian|  楼主 | 2018-1-7 12:50 | 只看该作者
窗口看门狗也是比较简单。

使用特权

评论回复
19
mintspring| | 2018-1-26 16:07 | 只看该作者
有什么用

使用特权

评论回复
20
Brand2| | 2018-1-26 16:30 | 只看该作者
窗口看门狗和独立看门狗什么差别,为什么两种

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

62

主题

1353

帖子

6

粉丝