#include "int.h"
void wdt_init_interrupt(void)
{
//设置8到15位,先清零然后再设值,2^8-1,先设定分频系数为66,那么66/66=1MHZ
WTCON &= ~(0xff<<8);
WTCON |= (65<<8);
//设值之后的分频,先两位清零然后 11 ,1/128,1.28us
WTCON |= (0x3<<3);
//开启中断(第2位),关闭复位(第0位)
WTCON |= (1<<2);
WTCON &= ~(1<<0);
//设置计数值了,就设置为200ms
WTDAT = 1562;
WTCNT = 1562;
//开启定时
}
void isr_key(void)
{
GPJ2DAT ^= (1<<0);
WTCLRINT = 1;
intc_clearvectaddr();
}
int main(void)
{
GPJ2CON &=~(0xffff);
GPJ2CON |= (0x1111);
GPJ2DAT |= (0xf<<0);
int_init();
wdt_init_interrupt();
intc_setvectaddr(NUM_WDT, isr_key);
intc_enable(NUM_WDT);
WTCON |= (1<<5);
while(1);
}
以上是闪灭一盏LED的代码。由看门狗设置为定时器定时LED闪灭
看门狗的频率设定:
时钟源为PLCK,PLCK=66MHZ,期间经过第一次分频和第二次分频,第一次分频可以不分频,第二次分频分为:16,32,64,128四种系列。第一次分频的系数范围为(0~2^8-1),例如:给定系数为65,那么系统自动在这个基础上加上1,为的是防止用户给定系统0的情况然后分频系数为0的情况出现!
需要注意的是:在使用看门狗的时候需要分清是用于复位还是定时器,系统默认是复位功能。定时器功能的时候WTCON的0位设为0第二位设为1,反之相反。
t_watchdog=1/(PCLK/(Prescaler value+1)/(Division_factor)
看门狗的周期=1/(66MHZ/(第一次分频系数+1)/(第二次分频系数)
WTDAT寄存器存放的值用于WTCNT寄存器存放的值减为零之后再赋给WTCNT,当WTCNT的值减为零之后那么就触发中断。在中断服务程序运行完之后需要将看门狗定时器中断消除,给WTCLRINT寄存器赋任何值即可。
将WTCON |=(1<<5)定时器开始语句放到最后是为了防止出现定时已经开始但是中断配置还未完成。
#include "int.h"
void wdt_init_interrupt(unsigned int prescaler,unsigned int clock_select,unsigned int cnt)
{
WTCON &= ~(0xff<<8);
WTCON |= (prescaler<<8);
switch(clock_select)
{
case 16:WTCON |= (0x0<<3); break;
case 32:WTCON |= (0x1<<3); break;
case 64:WTCON |= (0x2<<3); break;
case 128:WTCON |= (0x3<<3); break;
default: break;
}
WTCON |= (1<<0);
WTCNT = cnt;
}
int main(void)
{
GPJ2CON &=~(0xffff);
GPJ2CON |= (0x1111);
GPJ2DAT |= (0xf<<0);
GPH2CON &= ~(0xf<<0);
wdt_init_interrupt(65,128,39062);
WTCON |= (1<<5);
while(1)
{
if(((GPH2DAT)&(1<<0))==0)
{
while(((GPH2DAT)&(1<<0))==0);
GPJ2DAT ^=(1<<0);
WTCNT = 39062;
}
}
}
以上是看门狗复位功能,设置看门狗定时器的复位功能,看门狗的复位时间设置为5s,使用K2按键喂狗(给WTCNT赋初始值),观察5s之内没有按下K2,看门狗会复位的现象。按键使用轮询方式。
防止看门狗复位只要进行“喂狗”将WTCNT再赋一次初值即可。此程序中不用用到中断相关的函数。