Electronic – Atmega328P Watch Dog Timer – Delay Issue

atmega328pavrinterruptsmicrocontrollerwatchdog

I am trying to give delay of 0.5 seconds on 13 pin of the arduino using Watch Dog timer interrupt, the code complies and works fine but the led is blinking so rapidly that it seems like it is blinking at a delay of 50ms not with a delay of 0.5 second. Please help.
Thanks in advance.

#define F_CPU 16000000UL
#include<avr/io.h>
#include<avr/interrupt.h>
#include<avr/wdt.h>

int main(void)
{
  cli();
  wdt_reset();

  WDTCSR |=(1<<WDP2) | (1<<WDP0);

  WDTCSR |= (1<<WDIE);
  WDTCSR |= (1<<WDE);

  sei();

  DDRB |= 0b00100000;

  PORTB |= 0b00000000;

  while(1)
  {

  }
}

ISR(WDT_vect) {

 PORTB ^= 0b00100000;

}

Best Answer

If I read the datasheet (p.54-55) correctly, you have to set the WDCE bit in WDTCSR to be able to change the prescaler. The default setting for the prescaler bits is 000 or about a 16 ms delay.

Also, if you set both WDE and WDIE, the watchdog works in "Interrupt and System Reset Mode", where the first WD timeout triggers the interrupt, and a second one resets the device, unless the WDIE bit is set again after the interrupt. Or if you only want the interrupt, not the reset, just leave WDE unset.

So paraphrasing the example code, I think you'll want something like this:

cli();
WDTCSR |= (1<<WDCE);  /* enable change */
WDTCSR = (1<<WDIE) | (1<<WDP2) | (1<<WDP0);  /* enable interrupt and set prescaler */
sei();