Skip to main content
added 297 characters in body
Source Link
bigjosh
  • 10.2k
  • 34
  • 53

This is much easier than suggested above and elsewhere.

As long as the WDTON fuse is not programmed (it is not programmed by default), then you need only...

  1. Set the watchdog interrupt enable bit and the timeout in the watchdog control register.
  2. Enable interrupts.

Here is a code example that will execute an ISR once per second16ms...

ISR(WDT_vect) {
   // Any code here will get called onceeach pertime secondthe watchdog expires
}

void main(void) {
   WDTCR =  _BV(WDIE) | _BV( WDP2) | _BV( WDP1);    // Enable WDT interrupt, setleave existing timeout to(default 116ms) second
   sei();                                           // Turn on global interrupts
   // Put any code you want after here.
   // You can also go into deep sleep here and as long as 
   // global interrupts are eneabled, you will get woken 
   // up everywhen second.the watchdog timer expires
   while (1);
}

That is really it. Since we never enable the watchdog reset, we never have to mess around with the timed sequences to disable it. The watchdog interrupt flag automatically gets cleared when the ISR is called.

If you want a period different than every 1 second, you can use these values here to set the apropriate bits in WDTCR...

enter image description here

Note that you do need to execute the timed sequence to change the timeout. Here is code that sets the timeout to 1 second...

   WDTCR = _BV(WDCE) | _BV(WDE);                   // Enable changes
   WDTCR = _BV(WDIE) | _BV( WDP2) | _BV( WDP1);    // Enable WDT interrupt, change timeout to 1 second

This is much easier than suggested above and elsewhere.

As long as the WDTON fuse is not programmed (it is not programmed by default), then you need only...

  1. Set the watchdog interrupt enable bit and the timeout in the watchdog control register.
  2. Enable interrupts.

Here is a code example that will execute an ISR once per second...

ISR(WDT_vect) {
   // Any code here will get called once per second
}

void main(void) {
   WDTCR =  _BV(WDIE) | _BV( WDP2) | _BV( WDP1);    // Enable WDT interrupt, set timeout to 1 second
   sei();                                           // Turn on global interrupts
   // Put any code you want after here.
   // You can also go into deep sleep here and as long as 
   // global interrupts are eneabled, you will get woken up every second. 
   while (1);
}

That is really it. Since we never enable the watchdog reset, we never have to mess around with the timed sequences to disable it. The watchdog interrupt flag automatically gets cleared when the ISR is called.

If you want a period different than every 1 second, you can use these values here to set the apropriate bits in WDTCR...

enter image description here

This is much easier than suggested above and elsewhere.

As long as the WDTON fuse is not programmed (it is not programmed by default), then you need only...

  1. Set the watchdog interrupt enable bit and the timeout in the watchdog control register.
  2. Enable interrupts.

Here is a code example that will execute an ISR once per 16ms...

ISR(WDT_vect) {
   // Any code here will get called each time the watchdog expires
}

void main(void) {
   WDTCR =  _BV(WDIE);    // Enable WDT interrupt, leave existing timeout (default 16ms) 
   sei();                                           // Turn on global interrupts
   // Put any code you want after here.
   // You can also go into deep sleep here and as long as 
   // global interrupts are eneabled, you will get woken 
   // up when the watchdog timer expires
   while (1);
}

That is really it. Since we never enable the watchdog reset, we never have to mess around with the timed sequences to disable it. The watchdog interrupt flag automatically gets cleared when the ISR is called.

If you want a period different than every 1 second, you can use these values here to set the apropriate bits in WDTCR...

enter image description here

Note that you do need to execute the timed sequence to change the timeout. Here is code that sets the timeout to 1 second...

   WDTCR = _BV(WDCE) | _BV(WDE);                   // Enable changes
   WDTCR = _BV(WDIE) | _BV( WDP2) | _BV( WDP1);    // Enable WDT interrupt, change timeout to 1 second
Source Link
bigjosh
  • 10.2k
  • 34
  • 53

This is much easier than suggested above and elsewhere.

As long as the WDTON fuse is not programmed (it is not programmed by default), then you need only...

  1. Set the watchdog interrupt enable bit and the timeout in the watchdog control register.
  2. Enable interrupts.

Here is a code example that will execute an ISR once per second...

ISR(WDT_vect) {
   // Any code here will get called once per second
}

void main(void) {
   WDTCR =  _BV(WDIE) | _BV( WDP2) | _BV( WDP1);    // Enable WDT interrupt, set timeout to 1 second
   sei();                                           // Turn on global interrupts
   // Put any code you want after here.
   // You can also go into deep sleep here and as long as 
   // global interrupts are eneabled, you will get woken up every second. 
   while (1);
}

That is really it. Since we never enable the watchdog reset, we never have to mess around with the timed sequences to disable it. The watchdog interrupt flag automatically gets cleared when the ISR is called.

If you want a period different than every 1 second, you can use these values here to set the apropriate bits in WDTCR...

enter image description here