当受到各种各样的干扰而使GPRS DTU不能执行正常的程序时,需要了解看门狗定时器(WDT),它具有两种功能,其一作为普通的定时器,该模式下产生正常的定时中断信号;其二作为通常意义上的看门狗,用来复位单片机,避免单片机长时间处于不正常工作状态。看门狗程序只是用来把单片机从不正常的工作状态中拉回来,也就是说正常情况下,它是静默的,程序运行过程中必须在适当的时间间隔内喂狗。如果用户程序执行时间很长到不能满足喂狗时间,这时候应当将用户程序尽可能模块化、时间片化以满足喂狗时间。鉴于看门狗的工作职责,看门狗寄存器值的读写通常采用密码字+数据的方式,以防止单片机正常执行过程中对看门狗的误写。看门狗初始化和喂狗操作程序如下所示:
#include
#include "wdt.h"
/*******************************************
函数名称:看门狗初始化程序
功 能:看门狗设定32ms,看门狗时钟选择SMCLK
参 数:无
返回值 :无
********************************************/
void wdt_init(void)
{
WDTCTL = WDT_MRST_32; // 设定看门狗定时器32ms复位
}
/*******************************************
函数名称:喂狗程序
功 能:清零看门狗定时器计数值
参 数:无
返回值 :无
********************************************/
void wdt_clear(void)
{
WDTCTL = WDTPW + WDTCNTCL; // 清零看门狗定时器
}
该程序设定看门狗时钟采用SMCLK,设定最大喂狗时间为32ms,当用户程序在规定的32ms内没有清零看门狗定时器的计数值,看门狗定时器溢出,产生复位信号,最终复位单片机。注意到看门狗计数值清零与初始化为同一个寄存器,采用赋值的方式清零看门狗定时器计数值,同时会改变看门狗定时器的工作模式。本程序之所以可以按用户的设定运行,是因为看门狗定时器采用SMCLK时钟,喂狗操作正好不改变寄存器相应工作模式位的设定值。但是如果选择ACLK作为时钟,采用该喂狗操作就会影响看门狗的工作模式了。假如设定看门狗定时器1000ms复位,WDTCTL = WDT_ARST_1000;喂狗之后就变成32ms自动复位了。用户程序如果没有在32ms内喂狗,程序就一直停在复位了。
注意到设定模式时同时具有清零的功能,正常的喂狗程序即为初始化设置程序WDTCTL = WDT_ARST_1000。
#include
#include "wdt.h"
/*******************************************
函数名称:看门狗初始化程序
功 能:看门狗设定1000ms,看门狗时钟选择ACLK
参 数:无
返回值 :无
********************************************/
void wdt_init(void)
{
WDTCTL = WDT_ARST_1000; // 设定看门狗定时器1000ms复位
}
/*******************************************
函数名称:喂狗程序
功 能:清零看门狗定时器计数值
参 数:无
返回值 :无
********************************************/
void wdt_clear(void)
{
WDTCTL = WDT_ARST_1000; // 清零看门狗定时器
}
看门狗程序用来把单片机从不正常的工作状态中拉回来,也就是说不正常情况下,它是运作的,程序不正常运行过程中不应该满足喂狗条件,从而产生需要的复位信号,复位单片机。这样来看,喂狗程序不能放在中断中,因为主程序可能跑飞了,中断程序仍能正常工作,这样看门狗程序失去作用。