msp430看門狗定時器
看門狗定時器用來防止程式因供電電源、空間電磁干擾或其它原因引起的強烈干擾噪聲而跑飛的事故。在很多微控制器中都內建了看門狗,看門狗本身是一個定時器,當定時器溢位時即進行系統復位,因此需要在程式中對看門狗定時器進行清零,即常說的喂狗。
由於我用過AVR的微控制器,和AVR的相比,MSP430的看門狗要靈活的多,首先預設看門狗是開著的,因此如果不使用看門狗的話要關閉,指令如下:
WDTCTL = WDTPW + WDTHOLD
如果開啟看門狗則需要在程式中清零,指令如下:
WDTCTL=WDTPW+WDTCNTCL
這只是基本的應用,430的看門狗要稍微複雜一些,首先從IAR的標頭檔案中看看定義了幾種工作狀態:
- /* 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 " */
從標頭檔案的定義中可以看出主要有兩種方式,一種就是當做普通的定時器使用,一種才是作為看門狗,另外就是時鐘源可選,選擇8M或者32K的晶振來獲得不同的延時,通過上面可以看出看門狗定時器最大的時間可以到1S,在程式中可以靈活的利用看門狗定時器實現想要的功能。
下面介紹兩個典型應用:
1、在動態數碼管顯示中的應用,具體程式碼可以參考我之前的筆記,部分程式碼如下:
WDTCTL = WDT_ADLY_1_9; // 設定內部看門狗工作在定時器模式,1.9ms中斷一次
//可以去看標頭檔案中具體的配置,這裡使用的手錶晶振64分頻計算可得是1.9ms
IE1 |= WDTIE; // 使能看門狗中斷
__interrupt void watchdog_timer(void)
{
}
這個程式主要是將看門狗定時器當做普通定時器使用,1.9ms剛好適合動態掃描間隔,在看門狗中斷中對數碼管進行動態掃描,這樣使用相對於開一個定時器來說要有所方便。因此在需要的定時與看門狗定時器的幾個時間相同時可以考慮使用看門狗。
2、普通延時
WDTCTL = WDT_ADLY_1000; //間隔定時器,定時1000ms
//延時2s
for(i = 0; i < 3; i++)
{
IFG1 &= ~WDTIFG;
while(!(IFG1 & WDTIFG));
IFG1 &= ~WDTIFG;
}
這個程式同樣是將看門狗當普通定時器使用,在主程式中讀取中斷標誌位,實現延時效果,上面的程式為什麼是延時2S自己分析。
這裡面舉了兩個例子,是最近學習的一點小體會,當然還是不能忘了看門狗的本能工作,在程式較為簡單時可以考慮使用看門狗定時器簡化設計。另外還有一點覺得比較重要的是雖然標頭檔案中對暫存器都有了很好的定義,但是還是很有必要對著標頭檔案和暫存器把主要的暫存器看一面,弄清每一種工作模式的使用方式和注意點。