看門狗定時器(WDT:Watch Dog Timer)實際上是一個計數器。
一般給看門狗一個大數,程序開始運行后看門狗開始倒計數。
如果程序運行正常,過一段時間CPU應該發出指令讓看門狗復位,令其重新開始倒計數。
如果看門狗計數減到0,就認為程序沒有正常工作(因為沒有及時復位),就強制整個系統復位(單片機重啟)。
一般給看門狗一個大數,程序開始運行后看門狗開始倒計數。
如果程序運行正常,過一段時間CPU應該發出指令讓看門狗復位,令其重新開始倒計數。
如果看門狗計數減到0,就認為程序沒有正常工作(因為沒有及時復位),就強制整個系統復位(單片機重啟)。
所以,當你開啟看門狗后,需要在看門狗超時(計數減到0)前,對其進行 喂狗(復位)操作,否則看門狗會強制你的單片機重啟,從頭運行程序。
如果看門狗在休眠或空閑模式下超時,器件將喚醒並從PWRSAV指令執行處繼續執行代碼,同時“休眠”狀態位(RCON<3>)或“空閑”狀態位(RCON<2>)會置1,表示器件之前處於省電模式。
功能作用:看門狗可以在你的程序陷入死循環的時候,讓單片機復位而不用整個系統斷電,從而保護你的硬件電路。
使用看門狗需要引用頭文件 【 avr/wdt.h 】,在wdt.h中,提供了3個看門狗API:
wdt_enable(timeout) //看門狗啟動,並設置超時時間
wdt_disable() //看門狗停止
wdt_reset() //看門狗復位(喂狗)
wdt_enable(timeout) //看門狗啟動,並設置超時時間
wdt_disable() //看門狗停止
wdt_reset() //看門狗復位(喂狗)
wdt_enable(timeout) 中timeout為超時時間,當超過這個時間后沒有喂狗,則單片機重啟。
這個時間可使用如下常量:
// 0=15(16)ms, 1=30(32)ms,2=60(64)ms,3=120(128)ms,4=250ms,5=500ms
// 6=1 sec,7=2 sec, 8=4 sec, 9= 8sec
0、WDTO_15MS: 看門狗定時器15ms超時
1、WDTO_30MS: 看門狗定時器30ms超時
2、WDTO_60MS:看門狗定時器60ms超時
3、WDTO_120MS: 看門狗定時器120ms超時
4、WDTO_250MS: 看門狗定時器250ms超時
5、WDTO_500MS: 看門狗定時器500ms超時
6、WDTO_1S: 看門狗定時器1S超時
7、WDTO_2S: 看門狗定時器2S超時
8、WDTO_4S: 看門狗定時器4S超時
9、WDTO_8S: 看門狗定時器8S超時
這個時間可使用如下常量:
// 0=15(16)ms, 1=30(32)ms,2=60(64)ms,3=120(128)ms,4=250ms,5=500ms
// 6=1 sec,7=2 sec, 8=4 sec, 9= 8sec
0、WDTO_15MS: 看門狗定時器15ms超時
1、WDTO_30MS: 看門狗定時器30ms超時
2、WDTO_60MS:看門狗定時器60ms超時
3、WDTO_120MS: 看門狗定時器120ms超時
4、WDTO_250MS: 看門狗定時器250ms超時
5、WDTO_500MS: 看門狗定時器500ms超時
6、WDTO_1S: 看門狗定時器1S超時
7、WDTO_2S: 看門狗定時器2S超時
8、WDTO_4S: 看門狗定時器4S超時
9、WDTO_8S: 看門狗定時器8S超時
使用看門狗很簡單,只需要做下面三步即可:
1、引用頭文件 #include avr/wdt.h
2、Setup函數中啟動看門狗,並設置超時時間為兩秒:wdt_enable(WDTO_2S);
3、Loop函數中喂狗,防止餓死(重啟): wdt_reset();
代碼如下:
#include <avr/wdt.h>
int ledPin = 13;
void setup() {
pinMode(ledPin, OUTPUT);
//啟動看門狗,設置喂狗時間不能超過2秒
wdt_enable(WDTO_2S);
}
pinMode(ledPin, OUTPUT);
//啟動看門狗,設置喂狗時間不能超過2秒
wdt_enable(WDTO_2S);
}
void loop()
{
digitalWrite(ledPin, HIGH);
delay(500);
digitalWrite(ledPin, LOW);
//喂狗。如果超過2S沒有喂狗,則單片機重啟。
//也就是說,如果本循環執行時間超過2S的話,單片機就會自動重啟。
wdt_reset();
}
{
digitalWrite(ledPin, HIGH);
delay(500);
digitalWrite(ledPin, LOW);
//喂狗。如果超過2S沒有喂狗,則單片機重啟。
//也就是說,如果本循環執行時間超過2S的話,單片機就會自動重啟。
wdt_reset();
}
其它應用:
【利用看門狗進行休眠喚醒】
用下面的代碼,代替wdt_enable(),並且不要喂狗。
這樣就實現了看門狗超時后,執行喚醒函數,而不是重啟單片機。
【利用看門狗進行休眠喚醒】
用下面的代碼,代替wdt_enable(),並且不要喂狗。
這樣就實現了看門狗超時后,執行喚醒函數,而不是重啟單片機。
void wdt_setup(int ii) {
// ii為看門狗超時時間,支持以下數值:
// 0=16毫秒, 1=32毫秒,2=64毫秒,3=128毫秒,4=250毫秒,5=500毫秒
// 6=1秒 ,7=2秒, 8=4秒, 9=8秒
byte bb;
if (ii > 9 ) ii = 9;
bb = ii & 7;
if (ii > 7) bb |= (1 << 5);
bb |= (1 << WDCE);
//開始設置看門狗中斷
MCUSR &= ~(1<<WDRF); //清除復位標志
WDTCSR |= (1<<WDCE) | (1<<WDE);
//設置新的看門狗超時時間
WDTCSR = bb;
//設置為定時中斷而不是復位
WDTCSR |= _BV(WDIE);
//別忘了設置【看門狗喚醒執行函數】
}
// ii為看門狗超時時間,支持以下數值:
// 0=16毫秒, 1=32毫秒,2=64毫秒,3=128毫秒,4=250毫秒,5=500毫秒
// 6=1秒 ,7=2秒, 8=4秒, 9=8秒
byte bb;
if (ii > 9 ) ii = 9;
bb = ii & 7;
if (ii > 7) bb |= (1 << 5);
bb |= (1 << WDCE);
//開始設置看門狗中斷
MCUSR &= ~(1<<WDRF); //清除復位標志
WDTCSR |= (1<<WDCE) | (1<<WDE);
//設置新的看門狗超時時間
WDTCSR = bb;
//設置為定時中斷而不是復位
WDTCSR |= _BV(WDIE);
//別忘了設置【看門狗喚醒執行函數】
}
看門狗喚醒執行函數:
ISR(WDT_vect){
//喚醒后執行的代碼
}
//喚醒后執行的代碼
}