看门狗定时器有两个作用:
1、看门狗复位
可以设置看门狗定时器的计数值,计数值在看门狗的工作频率下不断的减
1,当计数值减到0,看门狗就会产生一个复位信号,造成了整个系统的复位。
例如:
看门狗的工作频率设置成
1000Hz,看门狗的计数值设置成10000;这样计数值每1ms减一次1,当10秒后计数值减到0。系统就会产生复位信号,系统重启。
系统正常工作的时候,我们应该
10秒钟内(计数值减到0之前)重新给计数值赋一个初始值,防止系统重启,这个过程叫“喂狗”。
当系统运行出错,程序
“跑飞”的时候,“喂狗”程序也停止工作,这样会出现10s之内不能喂狗,系统就会重启,让系统重新开始工作,恢复到正常工作状态。
简述:当系统受到干扰而产生死机(后者程序跑飞)的时候,看门狗可以让系统重启,重新开始工作。
2、普通的定时器(51单片机的定时器)
普通的定时器主要是用来计时。会产生周期性的中断,我们可以设置定时器的周期。
例:
我们可以设置定时器的工作频率
1000HZ,定时器的计数值设置成1000;这样当打开定时器中断,并开启定时器后,计数值就每1ms减一次1,当计数值减到0,就会生成一个中断,会执行一个中断服务程序,在中断服务程序中开始计时。计数值会自动的恢复到1000,开始下一个周期,周而复始…..
=========================================================
一、看门狗的框图
分频有什么用?
上章讲到
时钟源的由来
,他是由芯片外的
晶振产生时钟源
,通过倍频器,使得24mhz频率提高到1000MHZ,
然后通过分频,分到的看门狗的
PCLK_PSYS=66MHZ.
然后经过看门狗的分频器二次分频
得到一个基准频率。
这个所谓的基准频率,指的就是看门狗的基准周期,也就是现实生活中的一秒等于频率的多少
mhz
。
这里得到的
2022
就代表着 生成
2022
频率的时间代表
1
秒。
WTCON =(0xfe<<8);//
设置第一次分频值
255
WTCON |=(0x3<<3); //
设置第二次分频值
128 , 66000000/(254+1)/128 = 2022
程序设计
1、看门狗的复位功能
我们设置看门狗的复位时间
10s
,观察
10s
内没有喂狗,系统复位
……
//
看门狗
#define WTCON (*(volatile unsigned int *)0xE2700000)
#define WTDAT (*(volatile unsigned int *)0xE2700004)
#define WTCNT (*(volatile unsigned int *)0xE2700008)
#define WTCLRINT (*(volatile unsigned int *)0xE270000C)
1
)看门狗的初始化
WTCON =(0xfe<<8);//
设置第一次分频值
255
WTCON |=(0x3<<3); //
设置第二次分频值
128 , 66000000/(254+1)/128 = 2022
WTCON &=~(1<<2); //
设置看门狗中断 关
WTCON |=(1<<0); //
设置复位开关 开
WTCNT =20220;
//设置时间量,20220 代表10s ,10秒内若不喂狗。就会产生复位
WTDAT =20220; //
复位时间
10s.
2)打开看门狗
WTCON |=(1<<5); //
设置看门狗使能位
3)喂狗
WTCNT=WTDAT; //
喂狗
看门狗的复位时间一般都是秒级的。
——————————————————————————–
2、普通定时器功能
设置看门狗定时器的周期是
10ms
,利用看门狗定时器进行计时,使
LED1
每
400ms
翻转一次。
1)中断控制器的初始化
int_init();
2)看门狗中断的初始化
intc_setvectaddr(NUM_WDT, isr_wdt); //
看门狗中断的安装
3)看门狗定时器的初始化
void wdt_init(void)
{
WTCON =(0xfe<<8);//
设置第一次分频值
255
WTCON |=(0x3<<3); //
设置第二次分频值
128 , 66000000/(254+1)/128 = 2022
WTCON |=(1<<2); //
设置看门狗中断 开
WTCON &=~(1<<0); //
设置复位开关 关
WTCNT =20;
WTDAT =20; //
定时周期
10ms.
}
4)打开看门狗中断
intc_enable(NUM_WDT);
5)启动看门狗
WTCON |=(1<<5); //
设置看门狗使能位
当定时周期到了的时候,会执行中断服务程序:
void isr_wdt(void)
{
sum++; //
每
10ms
,
sum=sum+1
if(sum==40) //400ms
{
GPJ2DAT ^= (0x1<<0); //
翻转
LED1
sum=0; //
清
0
,准备下一次
400ms
的计数
}
WTCLRINT=1; //
清看门狗的中断
intc_clearvectaddr(); //
清中断控制器的中断
}