MSP430F5529 (二)看門狗的設置
所謂的看門狗功能,是指可以監控程序是否由于某些干擾或者錯誤而跑飛。其原理就是發生故障的時間滿足規定的定時時間后,產生一個非屏蔽中斷,使系統復位。這樣當在調試程序或預計程序在某個地方可能瞬時發生錯誤時(如外部電路干擾),選用設置看門狗定時中斷可以避免程序跑飛。
當然,它也可以用作一般的定時功能。
不過實際上,由于看門狗定時器(作看門狗使用時)需要很嚴密的設置(否則程序容易經常重啟),所以很多人都不會使用這項功能。所以,程序一開始就加上一句話:WDTCTL=WDTPW+WDTHOLD來關閉看門狗。
2.1 WDT_A的簡介
特點:
①有8種可選定時時間;
②看門狗模式;
③定時器模式;
④看門狗控制寄存器存在密碼保護;
⑤時鐘源可選,且具有時鐘源意外保護;
⑥可以被終止來節省能源;
⑦無論是用作看門狗還是定時器,其間隔時間都無法隨意設定,只能從8種設定中選擇,當然可以通過更改時鐘頻率來間接更改時間;
注意默認設置:程序啟動,看門狗即啟動;監控周期為32ms/32.768KHZ(也就是說當看門狗的時鐘頻率為32.768KHZ時,每過32ms,如果不軟件清空,程序就會重啟);所用的時鐘源為SMCLK(實際頻率不是32.768KHZ,后面會提到)。
2.2 WDT_A的寄存器及操作
注意:所有的寄存器都存字操作和字節操作模式。例如對WDTCTL寄存器直接賦值是字操作,你也可以通過WDTCTL_L(低字節寄存器)、WDTCTL_H來進行字節操作賦值。
該類寄存器只能賦值不要進行“|=、&=”等邏輯操作。
2.2.1看門狗控制寄存器WDTCTL(Watchdog Timer Control)
該寄存器是一個16位帶有密碼保護的讀寫寄存器。所謂的密碼保護,是為了防止該寄存器被不小心篡改。那么是如何實現密碼保護呢?事實上,該寄存器的高字節用來存放口令,低字節才是控制數據。寫口令為05Ah,讀口令為069h,任何和口令不一樣的高字節操作都會導致系統復位。
該寄存器的位功能定義如下:(支持位操作)

WDTPW:Bits15-8,WDT Password,寫為05Ah,讀為069h。
WDTHOLD:Bit7,WDT HOLD,
0:打開看門狗計時器;
1:關閉
WDTSSEL:Bits6-5,WDT Clock Source Select時鐘源選擇

WDTTMSEL:Bit4,工作模式選擇
0:看門狗模式;
1:定時器模式;
WDTCNTCL:Bit3,計時器清零
0:無效;
1:清空計數器,即WDTCNT=0x0000h
WDTIS: Bits2-0,WDT Interval Select,間隔時間選擇。用來選擇計數的周期,共有8種時間可以選擇。
備注:括號前數字為計數器的值

2.2.2 看門狗計數值寄存器WDTCNT(Watchdog Timer Counter)
這是一個32Bit的加計數器,但是不能通過軟件來直接對其進行賦值等操作,只能通過WDTCTL中的WDTIS來選擇時間。或者你可以通過WDTSSEL選擇不同的時鐘源,來間接改變時間。
2.2.3 看門狗中斷 位控制
WDT利用SFRS總寄存器中的兩位來控制中斷。
WDT中斷標志位:WDTIFG,位于SFRIFG1.0
WDT 中斷使能位:WDTIE,位于SFRIE1.0
看門狗模式:如果不及時對WDTCNT清零或者對WDT初始化,WDTIFG就會置位,然后程序就會重啟。
計時器模式:必須開總中斷GIE和看門狗中斷WDTIE。此外,當執行完中斷服務程序后,標志位WDTIFG會自動清零。
2.3常用操作
/*關閉看門狗*/
WDTCTL=WDTPW+WDTHOLD;
/*喂狗,即對有效狀態的看門狗進行清零操作*/
/*時間計滿還不喂狗就會導致程序重啟*/
/*WDTIS2即WDTIS=100,此時時間間隔設為1S,假定頻率為32.768KHZ*/
WDTCTL = WDTPW + WDTCNTCL+WDTSSEL0+WDTIS2;
/*將看門狗設置為計數器模式,計數8192約250ms,假定頻率為32.768KHZ*/
/* WDTIS2+WDTIS0即101*/
WDTCTL=WDTPW+WDTCNTCL+WDTTMSEL+WDTIS2+WDTIS0
總結例程:
/*首先將WDT設為定時器功能。而中斷服務子程序則是把WDT改為看門狗功能。這樣就通過中斷控制的周期性的重啟程序,實現了LED閃爍*/
/*注意,這里默認的時鐘源不是32KHZ,而是內部的DCO-SMCLK(之后會講到)1.045MHZ。所以前面WDTIS定義的時間大約都要縮小1045/32=32倍*/
#include <msp430.h>
void main(void)
{
/*清零-設定為計數器-時間設定為010模式,即256S/32=8S*/
WDTCTL=WDTPW+WDTCNTCL+WDTTMSEL+WDTIS1;
__enable_interrupt(); //開總中斷
SFRIE1|=WDTIE; //開看門狗定時器中斷
P1DIR=0xff;
int i,j;
P1OUT=0xff;
for(i=0;i<30000;i++)
for(j=0;j<50;j++); //延時約8S
P1OUT=0x00;
while(1);
}
/*中斷服務程序*/
#pragma vector=WDT_VECTOR
__interrupt void WatchTimer(void)
{
WDTCTL=WDTPW+WDTCNTCL+WDTIS1; //看門狗模式,時間設定約為8S
}
評論