2
\$\begingroup\$

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;

}
\$\endgroup\$
  • \$\begingroup\$ Try setting WDE to 0 rather than 1 - that should give you a 500ms interrupt with no system reset - with that code I would expect the system to reset every 500ms immediately after entering the ISR, and since you don't clear the interrupt flag, you enter that ISR immediately when you set WDIE after reset - toggling the pin. \$\endgroup\$ – Ken Sep 8 '16 at 19:02
  • \$\begingroup\$ Tried, still the problem is same. it is blinking so rapidly. \$\endgroup\$ – Mayank Pal Sep 8 '16 at 19:06
  • \$\begingroup\$ Are you sure you just don't need to clear the interrupt in the ISR? \$\endgroup\$ – DigitalNinja Sep 8 '16 at 19:55
  • \$\begingroup\$ The datasheet says "altera- tions to the Watchdog set-up must follow timed sequences" w.r.t. the "Watchdog change enable bit (WDCE)" and also has example code. Why don't you use that? \$\endgroup\$ – JimmyB Sep 8 '16 at 20:10
2
\$\begingroup\$

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();
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.