打印
[牛人杂谈]

看门狗

[复制链接]
1603|7
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
在由微控制器构成的微型计算机系统中, 由于微控制器的工作常常会受到来自外界电
磁场的干扰,造成程序的跑飞,而陷入死循环,程序的正常运行被打断,由微控制器控制
的系统无法继续工作,会造成整个系统的陷入停滞状态,发生不可预料的后果,所以出于
对微控制器运行状态进行实时监测的考虑, 便产生了一种专门用于监测微控制器程序运行
状态的芯片,俗称”看门狗”(watchdog) 。
看门狗电路的应用,使微控制器可以在无人状态下实现连续工作,其工作原理是:看
门狗芯片和微控制器的一个 I/O 引脚相连,并定时地往看门狗的这个引脚上送入高电平
(或低电平) ,这一程序语句是分散地放在微控制器其他控制语句中间的,一旦微控制器
由于干扰造成程序跑飞后而陷入某一程序段进入死循环状态时, 写看门狗引脚的程序便不
能被执行,这个时候,看门狗电路就会由于得不到微控制器送来的信号,便在它和微控制
器复位引脚相连的引脚上送出一个复位信号,使微控制器发生复位,即程序从程序存储器
的起始位置开始执行,这样便实现了微控制器的自动复位。
在以前传统的 8051 往往没有内置看门狗, 都是需要外置看门狗的, 例如常用的看门狗芯片有 Max813、 5045、 IMP706、 DS1232。
例如芯片 DS1232 在系统工作时如图 12.1.2,必须不间断的给引脚
----
ST输入一个脉冲系列,这个脉冲的时间间隔由引脚 TD 设定,如
果脉冲间隔大于引脚 TD 的设定值,芯片将输出一个复位脉冲使微控制器复位。一般将这个功能称为看门狗,将输入给看门狗的一系
列脉冲称为“喂狗”。这个功能可以防止微控制器系统死机。


DS1232 看门狗电路

虽然看门狗的好处是很多,但是其成本制约着是否使用外置看门狗抉择。不过幸运的是,现在很多微控制器都内置看门狗,例如
AVR、PIC、ARM,当然现在的 M451 系列微控制器也不例外,其已经内置了看门狗,而且基本上满足了项目的需要。

沙发
heisexingqisi|  楼主 | 2016-7-30 20:01 | 只看该作者
特征
 18 位的向上看门狗定时器可满足用户溢出时间间隔要求。
 溢出时间间隔(24 ~218)个 WDT_CLK 时钟周期可选,如 WDT_CLK = 10 kHz,那么溢出时间间隔是 1.6 ms ~ 26.214s。
 系统复位保持时间(1/WDT_CLK)*63 。
 支持看门狗定时器复位延时周期, 包括 1026、130、18 或 3 个 WDT_CLK 的复位延时时间。
 通过设置 CONFIG0 中 CWDTEN[2:0]位为 1,支持芯片上电或复位条件下看门狗强制打开。
 如果时钟源选择内部低速 10k 时钟或 LXT 时钟,支持看门狗定时器溢出唤醒。

使用特权

评论回复
板凳
heisexingqisi|  楼主 | 2016-7-30 20:04 | 只看该作者
使能看门狗超时中断和超时唤醒中断,设计程序让看门狗产生 3 次超时中断进行喂狗,3次过后则不执行喂狗,让系统复位.

1
void WDT_Open(uint32_t u32TimeoutInterval,
uint32_t u32ResetDelay,
uint32_t u32EnableReset,
uint32_t u32EnableWakeup)
位置:wdt.c
功能:初始化看门狗并启动计数
参数:
u32TimeoutInterval:看门狗超时时间
u32ResetDelay:看门狗复位延迟时间
u32EnableReset:是否使能复位
u32EnableWakeup:是否使能唤醒复位





2
void WDT_EnableInt(void)
位置:wdt.c
功能:使能看门狗触发中断
参数:无



3
WDT_RESET_COUNTER()
位置:wdt.h
功能:复位看门狗计数值
参数:无



4
WDT_GET_TIMEOUT_INT_FLAG()
位置:wdt.h
功能:获取看门狗超时中断标志位值
参数:无





5
WDT_CLEAR_TIMEOUT_INT_FLAG()
位置:wdt.h
功能:清零看门狗超时中断标志位值
参数:无



6
WDT_GET_TIMEOUT_WAKEUP_FLAG()

位置:wdt.h
功能:获取看门狗超时唤醒中断标志位值
参数:无



7
WDT_CLEAR_TIMEOUT_WAKEUP_FLAG()
位置:wdt.h
功能:清零看门狗超时唤醒中断标志位值
参数:无



使用特权

评论回复
地板
heisexingqisi|  楼主 | 2016-7-30 20:05 | 只看该作者
本帖最后由 heisexingqisi 于 2016-7-30 20:06 编辑
#include "SmartM_M4.h"
/*---------------------------------------------------------*/
/* 全局变量 */
/*---------------------------------------------------------*/
EXTERN_C INT32 IsDebugFifoEmpty(VOID);
VOLATILE UINT32 g_unWDTINTCounts;
VOLATILE UINT8 g_bIsWDTWakeupINT;
/*---------------------------------------------------------*/
/* 函数 */
/*---------------------------------------------------------*/
/****************************************
*函数名称:main
*输 入:无
*输 出:无
*功 能:函数主体
******************************************/
INT32 main(VOID)
{
PROTECT_REG
(
/* 系统时钟初始化 */
SYS_Init(PLL_CLOCK);
/* 使能看门狗时钟 */
CLK_EnableModuleClock(WDT_MODULE);
/* 看门狗时钟源为内部低速 10KHzRC*/
CLK_SetModuleClock(WDT_MODULE, CLK_CLKSEL1_WDTSEL_LIRC, 0);
/* 串口 0 初始化波特率为 115200bps */
UART0_Init(115200);
)
printf("+----------------------------------------+\n");
printf("| WDT Time-out Wake-up Sample Code |\n");
printf("+----------------------------------------+\n\n");
/* 检查复位是否看门狗复位导致 */
if(WDT_GET_RESET_FLAG() == 1)
{
WDT_CLEAR_RESET_FLAG();
printf("*** System has been reset by WDT time-out event ***\n\n");
while(1);
}
/* 使能看门狗 NVIC 中断 */
NVIC_EnableIRQ(WDT_IRQn);
/* 受保护的寄存器都进行解锁 */
SYS_UnlockReg();
g_unWDTINTCounts = g_bIsWDTWakeupINT = 0;
/* 设置看门狗超时时间为 2^14 次方看门狗时钟周期,看门狗延迟复位为 18 个看门狗时钟周期,启动看门狗计数 */
WDT_Open(WDT_TIMEOUT_2POW14, WDT_RESET_DELAY_18CLK, TRUE, TRUE);
/* 使能看门狗触发中断 */
WDT_EnableInt();
while(1)
{
/* 系统进入掉电模式前必须对受保护的寄存器进行解锁,因为改写 PWRCTL 寄存器需要对其解锁 */
SYS_UnlockReg();
printf("\nSystem enter to power-down mode ...\n");
/* 检查是否所有打印信息已经结束 */
while(IsDebugFifoEmpty() == 0);
/* 系统进入掉电模式 */
CLK_PowerDown();
/* 检查当前看门狗是否触发了超时中断和唤醒中断 */
while(g_bIsWDTWakeupINT == 0);
g_bIsWDTWakeupINT = 0;
/* 打印当前看门狗触发中断的次数 */
printf("System has been waken up done. WDT interrupt counts: %d.\n\n", g_unWDTINTCounts);
}
}
/*---------------------------------------------------------*/
/* 中断服务函数 */
/*---------------------------------------------------------*/
VOID WDT_IRQHandler(VOID)
{
if(g_unWDTINTCounts < 3)
{
/* 看门狗复位计数值亦即喂狗 */
WDT_RESET_COUNTER();
}
/* 检查当前看门狗触发的中断是否超时中断 */
if(WDT_GET_TIMEOUT_INT_FLAG() == 1)
{
/* 清除看门狗超时中断标志位 */
WDT_CLEAR_TIMEOUT_INT_FLAG();
g_unWDTINTCounts++;
}
/* 检查当前看门狗触发的中断是否超时唤醒中断 */
if(WDT_GET_TIMEOUT_WAKEUP_FLAG() == 1)
{
/* 清除看门狗超时唤醒中断标志位 */
WDT_CLEAR_TIMEOUT_WAKEUP_FLAG();
g_bIsWDTWakeupINT = 1;
}
}



使用特权

评论回复
5
heisexingqisi|  楼主 | 2016-7-30 20:07 | 只看该作者
主程序 main 分析:
a. 调用CLK_EnableModuleClock函数使能看门狗时钟, 并调用CLK_SetModuleClock设置看门狗时钟源为内部低速10KHzRC
振荡器。
b. 调用 WDT_GET_RESET_FLAG 函数检测当前的复位是否看门狗复位后进入初始化硬件流程的,若是,打印输出信息。
c. 调用 WDT_Open 函数设置看门狗超时时间为 2^14 次方看门狗时钟周期,看门狗延迟复位为 18 个看门狗时钟周期,启动看门狗
计数。
d. 调用 WDT_EnableInt 函数使能看门狗触发中断。
e. 当看门狗产生超时中断的时候,g_bIsWDTWakeupINT 将被置 1,通过 while(g_bIsWDTWakeupINT == 0)代码进行检测,
并打印输出看门狗产生中断的次数。
[4]中断服务函数 WDT_IRQHandler 分析
a. g_unWDTINTCounts 变量用于记录看门狗产生中断的次数,若小于 3 的时候,则调用 WDT_RESET_COUNTER 函数复位看门狗
计数值亦即喂狗;若等于 3 的时候,不喂狗,将会发生看门狗复位。
b. 调用 WDT_GET_TIMEOUT_INT_FLAG 函数获取当前看门狗是否触发超时中断, 若是, 则调用 WDT_CLEAR_TIMEOUT_INT_FLAG
清除当前标志位,且 g_unWDTINTCounts 自加 1。
c. 调 用 WDT_GET_TIMEOUT_WAKEUP_FLAG 函 数 检 测 当 前 看 门 狗 是 否 触 发 超 时 唤 醒 中 断 , 若 是 , 则 调 用

WDT_CLEAR_TIMEOUT_WAKEUP_FLAG 清除当前标志位,且 g_bIsWDTWakeupINT 置 1。

使用特权

评论回复
6
zhuotuzi| | 2016-7-31 18:23 | 只看该作者
/* 检查当前看门狗触发的中断是否超时中断 */
if(WDT_GET_TIMEOUT_INT_FLAG() == 1)
{
/* 清除看门狗超时中断标志位 */
WDT_CLEAR_TIMEOUT_INT_FLAG();
g_unWDTINTCounts++;
}

使用特权

评论回复
7
734774645| | 2016-7-31 21:49 | 只看该作者
一旦微控制器
由于干扰造成程序跑飞后而陷入某一程序段进入死循环状态时, 写看门狗引脚的程序便不
能被执行,这个时候,看门狗电路就会由于得不到微控制器送来的信号,便在它和微控制
器复位引脚相连的引脚上送出一个复位信号,使微控制器发生复位,即程序从程序存储器
的起始位置开始执行,这样便实现了微控制器的自动复位。

使用特权

评论回复
8
heisexingqisi|  楼主 | 2016-7-31 22:41 | 只看该作者
看门狗在保护系统不被死机的作用非常大。

使用特权

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

本版积分规则

131

主题

2615

帖子

2

粉丝