上一篇我们讲了定时器,今天的WDT看门狗定时器实际上就是一个定时器,只不过普通的定时器溢出是进入中断,而看门狗溢出就是直接复位重启单片机。
因为我没有在手册里找到看门狗的结构图,所以我们直接看库函数。
首先我们需要把STC32G_WDT.c包含进工程中。
使用WDT_Inilize这个函数对看门狗进行配置。
参数就一个结构体变量的指针,成员有仨,第一个是使能,第二个是模式,第三个是分频。
模式就两种。
一种是IDLE模式停止计数,另一种是继续计数,IDLE就是一种低功耗的工作模式,叫空闲模式,核心停止处理命令,但是外设什么的照常运行,没什么特殊要求我们就给个停止计数。
分频有八种,从 2^0 到 2^8 ,我们就是依靠分频数来设置看门狗的溢出周期的。
所以在STC中我们无法随意设置看门狗的溢出时间,因此需要根据自己项目的具体情况来选择最合适的溢出时间。
然后就是喂狗函数。
调用之后清空看门狗定时器的计数值。
有了上面两个函数之后我们就可以使用看门狗了……吗?
还有个很关键的一个问题,那就是如果我们仅仅配置了上面第一个函数,那么我们看门狗复位之后会直接进入USB下载模式,而不是重新执行程序。
接下来我们来看一个寄存器。
复位标志寄存器。
一共有5个bit,分别有不同的含义,我们可以通过读取这个寄存器的每个位来得知单片机是因为什么而复位的。
如果是因为电压过低而复位的,bit0就会被置1。
如果是因为看门狗而复位的,bit1就会被置1。
如果是因为软件复位的,bit2就会被置1。
如果是CPU执行到了代码区之外也就是代码溢出而复位的话,bit3会被置1。
如果是外部RST引脚造成的复位,那么bit4会被置1。
上面五个bit都可以通过读来得知复位的情况。
如果我们写入0则是没有任何用的,如果写入1的话,就是把对应的标志位清除。
我们需要在看门狗开启之后,把bit2给清除,否则看门狗复位就是会进入USB下载模式,因为P32被拉低了。
#include <STC32G.H>
#include "STC32G_GPIO.h"
#include "STC32G_Delay.h"
#include "STC32G_WDT.h"
void GPIO_Init(void){
P2_MODE_OUT_PP(GPIO_Pin_7);
P27 = 1;
}
void WDT_Init(void){
WDT_InitTypeDef initer;
initer.WDT_Enable = ENABLE; // 开启看门狗
initer.WDT_IDLE_Mode = WDT_IDLE_STOP; // 停止计数模式
initer.WDT_PS = WDT_SCALE_64; // 64分频,我们使用24MHz的主频,所以看门狗溢出周期为1.048576s
WDT_Inilize(&initer);
}
void main(void){
uint8 i = 0;
WTST = 0; //设置程序指令延时参数,赋值为0可将CPU执行指令的速度设置为最快
EAXSFR(); //扩展SFR(XFR)访问使能
CKCON = 0; //提高访问XRAM速度
GPIO_Init();
P27 = 0;
WDT_Init();
WDT_Clear(); // 先喂一次狗
RSTFLAG |= 0x04; // 把软复位标志清除
while(1){
for(i = 0; i < 3; ++i){
delay_ms(1000);
WDT_Clear();
}
P27 = 1;
delay_ms(2000);
}
return ;
}
上面的代码里我设置了看门狗的溢出周期为1.048576,通过上面的计算公式可以算得出来。
然后我们每隔1s喂一次狗,喂三次之后将P27置高电平,然后延时两秒,这时候就会触发看门狗复位。
我们在P27接个LED,看到的效果就会是LED亮三秒然后灭一秒这样循环。