1、 看门狗作用
单片机复位的方式:硬件复位 -- reset按键
上电复位 -- 电容
看门狗复位
看门狗的复位功能主要是用于一些平常难以操作的场合去帮助我们进行复位操作。当你单片机突然死机或者程序跑飞了,看门狗就可以检测得到并且及时帮你复位。看门狗也可以帮助提高系统的可靠性。看门狗本质就是一个计数器。
2、STM32的看门狗分类
此器件具有两个嵌入式看门狗外设,具有安全性高、定时准确及使用灵活的优点。两个看门狗外设(独立和窗口)均可用于检测并解决由软件错误导致的故障;当计数器达到给定的超时值时,触发一个中断(仅适用于窗口型看门狗)或产生系统复位。独立看门狗 (IWDG) 由其专用低速时钟 (LSI) 驱动,因此即便在主时钟发生故障时仍然保持工作状态。窗口看门狗 (WWDG) 时钟由 APB1 时钟经预分频后提供,通过可配置的时间窗口来检测应用程序非正常的过迟或过早的操作。IWDG 最适合应用于那些需要看门狗作为一个在主程序之外,能够完全独立工作,并且对时间精度要求较低的场合。 WWDG 最适合那些要求看门狗在精确计时窗口起作用的应用程序。
3、独立看门狗
STM32独立看门狗简介
自由运行递减计数器
时钟由独立 RC 振荡器提供(可在待机和停止模式下运行)当递减计数器值达到 0x000 时产生复位(如果看门狗已激活)
当通过对关键字寄存器 (IWDG_KR) 写入值 0xCCCC 启动独立看门狗时,计数器开始从复位
值 0xFFF 递减计数。当计数器计数到终值 (0x000) 时会产生一个复位信号( IWDG 复位)。
任何时候将关键字 0xAAAA 写到 IWWDG_KR 寄存器中, IWDG_RLR 的值就会被重载到计
数器,从而避免产生看门狗复位。看门狗要开始工作:要往IWDG_KR寄存器里写入0xCCCC接下来看门狗就会开始从IWDG_RLR 的值开始递减。如果一直减到0都没有给它写入0xAAAA,就会产生一次复位,此时来指示当前系统出问题了。这个总体的时间是可以自己决定的。
看门狗饿了,就要喂它,不喂它就咬你
独立看门狗框架
独立看门狗寄存器
IWDG_PR和IWDG_RLR是受到写保护的
要解除写保护就要往KR寄存器里写入0x5555的值
频率是在30kHZ到60kHZ之间变化:
Psc:4分频, RLR:1000
最早喂狗时间:4 / 60000 * 1000= 66.7ms
最晚喂狗时间:4 / 30000 * 1000 = 132ms
喂狗时间应该挑早喂的
解除写保护(往KR寄存器写0x5555)
预分频值(往PR寄存器写值)
重装载值(往RLR寄存器写值)
先让重装载值加载到计数器里(往KR寄存器写0xaaaa)
启动看门狗(往KR寄存器写0xcccc)
#include "iwdg.h"
/************************************
函数功能:独立看门狗的初始化
函数形参:u8 prer, u16 rlr
函数返回值:void
函数说明:
作者:
日期:
************************************/
void IWDG_Init(u8 prer, u16 rlr)
{
//解除写保护
IWDG->KR = 0X5555;
//预分频值(往PR寄存器写值)
IWDG->PR = 0;
//重装载值(往RLR寄存器写值)
IWDG->RLR = 5000;
//启动看门狗
IWDG->KR = 0XCCCC;
}
4、窗口看门狗
窗口看门狗特征
窗口看门狗通常被用来监测,由外部干扰或不可预见的逻辑条件造成的应用程序背离正常的运行序列而产生的软件故障。除非递减计数器的值在 T6 位变成 0前被刷新,看门狗电路在达到预置的时间周期时,会产生一个 MCU 复位(过晚喂狗)。如果在递减计数器达到窗口寄存器值之前刷新控制寄存器中的 7 位递减计数器值,也会产生 MCU 复位(过早喂狗)。这意味着必须在限定的时间窗口内刷新计数器。
● 可编程的自由运行递减计数器
● 复位条件
— 当递减计数器值小于 0x40 时复位(如果看门狗已激活)--过晚喂狗
— 在窗口之外重载递减计数器时复位(如果看门狗已激活)-- 过早喂狗
● 提前唤醒中断 (EWI):当递减计数器等于 0x40 时触发(如果已使能且看门狗已激活)
窗口看门狗框架
Twwdg = 42M*4096 * 8 -- 代表每减一次的时间
当前从0x7f开始递减到0x40所需要的时间
现在如果是8分频,则每减一次的时间是:0.00078s = 0.78ms = 780us
窗口看门狗寄存器
位7:代表使能窗口看门狗
位6:0--计数器的值
位9:代表使能窗口看门狗的中断
位8:7 -- 代表当前的分频值
位6:0 -- 代表需要设置的窗口值
进入中断就需要靠这个标志位
不用中断这个标志位也会置1,只是不会进入中断服务函数
打开WWDG的时钟
写入分频值(CFR寄存器里的WDGTB)--决定记一次数的时间
写入重装载值(CR寄存器里的0-6位)
设置窗口值
使能窗口看门狗的中断
配置优先级
核心响应中断
使能看门狗
编写中断服务函数
注意:使用窗口值的时候,需要把CR1寄存的相关操作提前到设置窗口值之前,否则就会一直复位,
#include "wwdg.h"
/************************************
函数功能:窗口看门狗的初始化
函数形参:u8 prer, u16 rlr
函数返回值:void
函数说明:选择8分频,每减一次需要78us
Twwdg = 42M*4096*8----代表每减一次的时间
当前从0x7f降到0x40所需的时间
现在如果是八分频,则没减一次的时间是0.00078s = 0.78 ms = 78us
作者:
日期:
************************************/
void WWDG_Init(void)
{
//1.打开WWDG时钟
RCC->APB1ENR |= 0X1 << 11;
//2. 写入分频值(往PR寄存器写值)
WWDG->CFR |= 0x3 << 7;
//3. 写入重装载值(往CR寄存器写值)
WWDG->CR |= 0X7F;
//8. 使能窗口看门狗
WWDG->CR |= 0X1 << 7;
//4. 设置窗口值
WWDG->CFR &= ~(0X7F<<0);
WWDG->CFR |= 0X6F<<0;
//5. 使能窗口看门狗的中断
WWDG->CFR |= 0X1 << 9;
//6. 配置中断优先级
NVIC_SetPriority(WWDG_IRQn,NVIC_EncodePriority(7-2,1,1));
//7. 使能核心响应中断
NVIC_EnableIRQ(WWDG_IRQn);
}
//10. 编写中断服务函数
void WWDG_IRQHandler(void)
{
//清零操作
WWDG->SR &= ~(0X1 << 0);
WWDG->CR |= 0X7F;
printf("窗口看门狗\r\n");
}
/************************************
函数功能:喂窗口看门狗
函数形参:void
函数返回值:void
函数说明:
作者:
日期:
************************************/
void WWDG_feed(void)
{
WWDG->CR |= 0X7F;//喂狗
}