看门狗的原理:
我见过的看门狗一般分为两种:
一种是看门狗本身是个定时器,设定好时钟和初值后,如果在定时时间到达之前不喂狗(清除某个寄存器或置位某个位),
芯片就会产生一个中断或者复位(像S3C2440A);
另一种就是像NUC140这样的,定时时间到了以后会产生一个中断,然后延迟1024个看门狗时钟周期后才会复位芯片。
这两种都需要喂狗,但是喂狗的语句所放置的地方就不同了。
对于第一种情况,可以把喂狗放到主程序的循环体中,但是因为一般不确定程序完整循环一次需要多长时间,而且由于还会有
其他的中断打断,所以多数情况下还需要另外一个定时器每隔一段时间喂狗。
就好像早期的51芯片,看门狗其实就是两个定时器,一个负责复位,另一个喂狗。
但NUC140就不需要,由于NUC140看门狗时间到了以后产生中断,之后会有1024个看门狗时钟的时间之后,才会复位芯片,
所以我们就可以把喂狗的语句放在看门狗的中断服务函数里面。
在此给大家个小建议,就是看门狗程序调试通过之后,在之后或者是模块调试的时候,不要加看门狗,
等到程序全部OK了以后再加看门狗,不然经常会出现程序下载到一半芯片复位,又或者是下载到RAM而非FLASH的时候,下载不进去等
不希望出现的情况发生。
好了下面看程序,程序比较简单。
先是头文件
#ifndef watch_dog_h
#define watch_dog_h
#include "DrvTimer.h"
#include "DrvSYS.h"
extern void initialize_watchdog (void); //初始化看门狗
#endif
然后是C文件
/*****************************************
*文件名: watch_dog.c *
*功能: 看门狗配置文件 *
*****************************************/
#include "watch_dog.h"
/**************************************************
*函数名:feed_watchdog *
*功能: 看门狗喂狗程序 *
*出口参数:无 *
*入口参数:无 *
**************************************************/
void feed_watchdog (void)
{
WDT->WTCR.WTIF = 1; //清看门狗中断标志
DrvSYS_UnlockProtectedReg (); //解锁受保护的系统寄存器
DrvWDT_Ioctl(E_WDT_IOC_RESET_TIMER, 0); //清除看门狗定时器即喂狗
DrvSYS_LockProtectedReg (); //对系统寄存器上锁
}
/**************************************************
*函数名:initialize_watchdog *
*功能: 初始化看门狗 *
*出口参数:无 *
*入口参数:无 *
**************************************************/
void initialize_watchdog (void)
{
DrvSYS_UnlockProtectedReg (); //解锁受保护的系统寄存器
DrvSYS_SelectIPClockSource (E_SYS_WDT_CLKSRC, 0x03); //设置看门狗的时钟源为内部10KHz振荡
DrvWDT_Open (E_WDT_LEVEL6); //使能看门狗的时钟,设置间隔为6.5S(等级5),并且先禁用看门狗定时器并重置
DrvWDT_Ioctl(E_WDT_IOC_ENABLE_INT, 0); //使能看门狗中断(及使能对应的向量中断控制位)
DrvWDT_Ioctl(E_WDT_IOC_ENABLE_RESET_FUNC, 0); //使能看门狗复位
DrvWDT_InstallISR ((WDT_CALLBACK)feed_watchdog); //安装看门狗中断回调函数
DrvWDT_Ioctl(E_WDT_IOC_START_TIMER, 0); //使能看门狗计时器,开始计时
DrvSYS_LockProtectedReg (); //对系统寄存器上锁
}