单片机经常工作在环境干扰比较大的环境中,容易受到各种各样的干扰而使单片机不能执行正常的程序。MSP430片内集成了看门狗定时器(WDT),具有两种功能,其一作为普通的定时器,该模式下产生正常的定时中断信号;其二作为通常意义上的看门狗,用来复位单片机,避免单片机长时间处于不正常工作状态。
鉴于看门狗的工作职责,看门狗寄存器值的读写通常采用密码字+数据的方式,以防止单片机正常执行过程中对看门狗的误写。MSP430F169简单的看门狗初始化和喂狗操作程序如下所示:
#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; // 清零看门狗定时器
}
接下来从看门狗要实现的功能来谈谈看门狗程序应该具备的条件和应用环境。看门狗程序只是用来把单片机从不正常的工作状态中拉回来,也就是说正常情况下,它是静默的,程序运行过程中必须在适当的时间间隔内喂狗。如果用户程序执行时间很长到不能满足喂狗时间,这时候应当将用户程序尽可能模块化、时间片化以满足喂狗时间。这个时候可能需要较好的编译软件支撑,最好编译软件具有时间剖析功能。在剖析用户程序代码执行时间的时候还应当注意整体的运行情况,比如用户程序执行可能很快,满足喂狗时间,但用户程序可能经常被其它中断程序抢占,用户程序执行一遍的时间可能远远超过喂狗时间,从而引起不正常的看门狗复位。
看门狗程序用来把单片机从不正常的工作状态中拉回来,也就是说不正常情况下,它是运作的,程序不正常运行过程中不应该满足喂狗条件,从而产生需要的复位信号,复位单片机。这样来看,喂狗程序不能放在中断中,因为主程序可能跑飞了,中断程序仍能正常工作,这样看门狗程序失去作用。