#include <avr/wdt.h> // Watchdog timer
const byte LED = 13;
const byte DURATION = WDTO_500MS;
uint8_t led = LOW;
ISR (WDT_vect) { // ISR
// The datasheet says we should not set WDIE from within this ISR, but we are going to ignore that
wdt_setup(DURATION);
digitalWrite(LED, led);
led ^= (HIGH^LOW);
}
void handleOtherStuff() {
delay(250);
}
void wdt_setup(uint8_t duration)
{
// We assume interrupts are disabled for the duration of this routine
wdt_reset(); // make sure the wdt does not expire while we are configuring it
uint8_t v1 = (1<<WDCE) // set the Watchdog Change Enable bit (HW will clear this bit in 4 cycles)
| (1<< WDE) // you have to set WDE in order to clear it in the next instruction
| (1<<WDIF); // clear the Watchdog Interrupt Flag by writing '1' to the bit
uint8_t v2 = (0<< WDE) // clear the Watchdog Reset Enable (we don't want to reset the chip when the watchdog expires)
| (1<<WDIE) // set Watchdog Interrupt Enable
| duration&0x7
| ((duration&0x8)<<2);
MCUSR = 0; // specifically, clear the WDRF bit
// These next two writes have to happen within 4 cycles
WDTCSR = v1;
WDTCSR = v2;
}
void setup() {
wdt_disable();
// configure the pins
pinMode(LED, OUTPUT);
noInterrupts();
wdt_setup(DURATION);
interrupts();
}
void loop() {
handleOtherStuff();
}
In this example, we use the watch dog timer to blink the LED at 1 Hz.