看门狗定时器WDT(Watch Dog Timer),俗称看门狗,是微控制器运行状态的监控系统,在微控制器内部程序跑飞后,微控制器的控制功能将进入混乱状态,这个时候看门狗将复位微控制器,重启系统控制,避免产生不可预料的后果。
MSP430内部集成了16位的看门狗定时器,在需要看门狗的应用中,该定时器可以作为看门狗使用;在一些不需要看门狗的设计中,看门狗定时器可以配置为普通定时器使用,最大化利用片上资源。
看门狗定时器的配置主要由**看门狗控制寄存器(WDTCTL)**控制,WDTCTL是一个16位具备密码保护机制的寄存器,其中高8位(WDTPW)为密码位,低8位为配置位。每次对WDTCTL写操作需要对高8位(WDTPW)写入0x5A,才能正常写入,如果写操作写入的不是0x5A,单片机将导致一次系统上电清除(PUC),这就是保护机制在起作用。对WDTCTL的读操作,高8位(WDTPW)的读取返回值一定是0x69。下面介绍WDT配置寄存器的控制功能及配置方法:
SFR_16BIT(WDTCTL); /* Watchdog Timer Control */
/* The bit names have been prefixed with "WDT" */
#define WDTIS0 (0x0001)
#define WDTIS1 (0x0002)
#define WDTSSEL (0x0004)
#define WDTCNTCL (0x0008)
#define WDTTMSEL (0x0010)
#define WDTNMI (0x0020)
#define WDTNMIES (0x0040)
#define WDTHOLD (0x0080)
#define WDTPW (0x5A00)
/* WDT-interval times [1ms] coded with Bits 0-2 */
/* WDT is clocked by fSMCLK (assumed 1MHz) */
#define WDT_MDLY_32 (WDTPW+WDTTMSEL+WDTCNTCL) /* 32ms interval (default) */
#define WDT_MDLY_8 (WDTPW+WDTTMSEL+WDTCNTCL+WDTIS0) /* 8ms " */
#define WDT_MDLY_0_5 (WDTPW+WDTTMSEL+WDTCNTCL+WDTIS1) /* 0.5ms " */
#define WDT_MDLY_0_064 (WDTPW+WDTTMSEL+WDTCNTCL+WDTIS1+WDTIS0) /* 0.064ms " */
/* WDT is clocked by fACLK (assumed 32KHz) */
#define WDT_ADLY_1000 (WDTPW+WDTTMSEL+WDTCNTCL+WDTSSEL) /* 1000ms " */
#define WDT_ADLY_250 (WDTPW+WDTTMSEL+WDTCNTCL+WDTSSEL+WDTIS0) /* 250ms " */
#define WDT_ADLY_16 (WDTPW+WDTTMSEL+WDTCNTCL+WDTSSEL+WDTIS1) /* 16ms " */
#define WDT_ADLY_1_9 (WDTPW+WDTTMSEL+WDTCNTCL+WDTSSEL+WDTIS1+WDTIS0) /* 1.9ms " */
/* Watchdog mode -> reset after expired time */
/* WDT is clocked by fSMCLK (assumed 1MHz) */
#define WDT_MRST_32 (WDTPW+WDTCNTCL) /* 32ms interval (default) */
#define WDT_MRST_8 (WDTPW+WDTCNTCL+WDTIS0) /* 8ms " */
#define WDT_MRST_0_5 (WDTPW+WDTCNTCL+WDTIS1) /* 0.5ms " */
#define WDT_MRST_0_064 (WDTPW+WDTCNTCL+WDTIS1+WDTIS0) /* 0.064ms " */
/* WDT is clocked by fACLK (assumed 32KHz) */
#define WDT_ARST_1000 (WDTPW+WDTCNTCL+WDTSSEL) /* 1000ms " */
#define WDT_ARST_250 (WDTPW+WDTCNTCL+WDTSSEL+WDTIS0) /* 250ms " */
#define WDT_ARST_16 (WDTPW+WDTCNTCL+WDTSSEL+WDTIS1) /* 16ms " */
#define WDT_ARST_1_9 (WDTPW+WDTCNTCL+WDTSSEL+WDTIS1+WDTIS0) /* 1.9ms " */
/* INTERRUPT CONTROL */
/* These two bits are defined in the Special Function Registers */
/* #define WDTIE 0x01 */
/* #define WDTIFG 0x01 */
看门狗定时时长选择位(WDTISx):
WDTISx = 00,32768个WDT时钟源周期。
WDTISx = 01,8192个WDT时钟源周期。
WDTISx = 10,512个WDT时钟源周期。
WDTISx = 11,64个WDT时钟源周期。
看门狗时钟源选择位(WDTSSEL):
WDTSSEL = 0,WDT时钟源为SMCLK。
WDTSSEL = 1,WDT时钟源为ACLK。
注意:看门狗定时器WDT工作在看门狗模式下,会承担监控微控制器的运行状态的工作,首先要保证看门狗定时器WDT能正常稳定地工作,这个时候看门狗定时器的时钟源有效性就显得尤为重要。MSP430系列微控制器为了确保时钟的有效性,设计了时钟失效安全机制。当看门狗定时器的时钟源ACLK或SMCLK失效的时候,WDT的时钟源不通过软件的干涉,就直接会切换到到MCLK,这种情况下,MCLK来源于外部时钟。但是如果外部时钟也失效了,微控制器内部的DCO会被自动激活,并作为MCLK的时钟为WDT继续提供时钟振荡。
看门狗定时器清零寄存器(WDTCNTCL):WDTCNTCL = 1,看门狗定时器的16位计数器将被清零,清零完成后WDTCNTCL位会自动复位为0。看门狗定时器的16位计数器不能直接访问,只能通过WDTCNTCL 对其进行清零操作。
看门狗定时器模式选择位(WDTTMSEL):用于选择WDT是工作在看门狗模式或定时器模式
WDTTMSEL = 0,看门狗定时器工作在看门狗模式;
WDTTMSEL = 1,看门狗定时器工作在普通定时器模式。
看门狗不可屏蔽中断使能位(WDTNMI):
WDTNMI = 0,复位管脚(RST)作为低电平复位输入管脚;
WDTNMI = 1,复位管脚(RST)作为不可屏蔽中断输入管脚。
每个单片机都有复位引脚,但这个引脚也可以不做复位用途。当复位管脚作为不可屏蔽中断(NMI)管脚使用时,该中断和普通I/O一样有中断子函数,区别是不可屏蔽中断(NMI)不需要开总中断使能(因为不可屏蔽,所以优先级最高),不可屏蔽中断(NMI)每次中断后会自动关闭不可屏蔽中断(NMI)使能。
看门狗不可屏蔽中断边沿选择位(WDTNMIES):
WDTNMIES = 0,复位管脚(RST)上的上升沿引发不可屏蔽中断;
WDTNMIES = 1,复位管脚(RST)上的下降沿引发不可屏蔽中断。
与看门狗不可屏蔽中断使能位(WDTNMI)配合使用。
看门狗定时器停止位(WDTHOLD):单片机复位后会自动打开看门狗,所以在不使用看门狗或对其进行配置之前,均需要先关闭看门狗后再进行操作(避免意外复位)。对于不使用看门狗的应用,可以使用该位关闭看门狗定时器模块来降低功耗。
看门狗密码位(WDTPW):前文有提,每次改写WDTCTL前,必须输入约定“密码”0x5A,否则将复位单片机。
声明:自本记开始,我都会以Ti官方给的某一两个例程来记并作注释,其他例程请按本记内容分析解读即可。
示例一:将看门狗定时器用作通用定时器,代码的作用是设置看门狗定时器的中断间隔为32ms,中断一次,P1.0管脚的输出电平就翻转一次。
#include <msp430g2553.h>
void main(void)
{
WDTCTL = WDT_MDLY_32; //设置看门狗定时器的时间间隔为32ms
IE1 |= WDTIE; //使能看门狗定时器中断
P1DIR |= BIT0; //设置P1.0管脚为输出方向
_BIS_SR(LPM0_bits + GIE); //进入LPM0低功耗模式,并使能全局中断
}
//看门狗定时器中断服务函数
#pragma vector=WDT_VECTOR
__interrupt void watchdog_timer(void)
{
P1OUT ^= BIT0; //翻转P1.0管脚输出电平
}
示例二:看门狗定时器工作在看门狗模式下。MSP430的I/O输出寄存器在单片机复位之后会保持在之前的状态。代码中看门狗处于工作状态,但由于缺乏看门狗清零(喂狗)处理,所以看门狗将会在默认的32768个时钟周期后,复位重启(看门狗溢出复位),表现为P1.0管脚的输出电平翻转。
#include <msp430g2553.h>
void main(void)
{
P1DIR |= BIT0; //设置P1.0管脚为输出方向
P1OUT ^= BIT0; //翻转P1.0管脚输出电平
_BIS_SR(LPM4_bits); //停止所有时钟,让单片机进入LPM4低功耗模式
}
我也会将帮助我很大的一本PDF书籍及配套代码放在我的资源里,需要的可自行下载阅读,官方头文件不懂的可以稍微等一等,后面的笔记会有介绍。