0
\$\begingroup\$

I am going through datasheet of AVR2560V. In page 65 , table 12-1, it says that AVR2560 has 3 mode for watchdog

  1. Interrupt mode - WDE = 0, WDIE = 1
  2. Reset Mode - WDE = 1, WDIE = 0
  3. Both - WDE = 1, WDIE = 1

This means if we want to use watchdog timer as source of Interrupt, then i should disable WDE. Am i right? Because when i disabling WDE in code, Watchdog timer is getting disabled.I had look at this link also and even he is doing the same. WDE make sense that it need to be enabled, just that table in the datasheet is confusing me. Can anyone please help me in clearing out this doubt.

Below is the Watchdog_init function which i am using.

 Watchdog_init(){
        MCUSR &= ~(1<<WDRF);

        WDTCSR |= (1<<WDCE) | (1<<WDE); // as per datasheet WDE should be 0?

        // timeout in 8 second
        WDTCSR = 1<<WDP0 | 1<<WDP3;

        // watchdog interrupt enabler
        WDTCSR |= _BV(WDIE);
    }
\$\endgroup\$

2 Answers 2

2
\$\begingroup\$

You have multiple writes to WDTCSR:

  1. Set WDCE and WDE, leaving the rest garbage
  2. Set WDP0 and WDP3, and clear the rest
  3. Set some other bits according to the _BV macro, leaving the rest as they were

So your step 1 is getting wiped out by step 2.

I'd suggest combining all three into a single assignment.

\$\endgroup\$
0
4
\$\begingroup\$

This means if we want to use watchdog timer as source of Interrupt, then i should disable WDE. Am I right?

Correct - WDE should not be set if you want to use WD in interrupt mode.

Because when i disabling WDE in code, Watchdog timer is getting disabled.

This is not correct. WDE stands for Watchdog System Reset Enable. The Watchdog timer is actually always running no matter what. The WDE and the WDIE bits only determine what what happens when the timer hits the timeout.

Your code for setting up WD interrupt mode is basically correct, except...

  1. It is good practice to turn off interrupts while changing the WDTCSR because if an int happened in between the time when you enable changes and tried to actual make the change, then more than 4 cycles would have elapsed and the change would fail.
  2. It is slightly more efficient to set all the bits in WDTCSR at once.

    Watchdog_init() {    
    
    
        // Just to be safe since we can not clear WDE if WDRF is set
        MCUSR &= ~(1<<WDRF);
    
    
        // disable interrupts so we do not get interrupted while doing timed sequence
        cli()
    
        // First step of timed sequence, we have 4 cycles after this to make changes to WDE and WD timeout
        WDTCSR |= (1<<WDCE) | (1<<WDE); 
    
        // timeout in 8 second, disable reset mode. Must be done in one operation
        WDTCSR = 1<<WDP0 | 1<<WDP3;
    
        // enable global interrupts
        sei();
    
        // enable watchdog interrupt only mode 
        WDTCSR |= _BV(WDIE);
    

    }

Other things to check:

  1. Make sure global interrupts are enabled or else the interrupts will happen but will not run your handler.
  2. Make sure that the WDTON fuse is not programmed or else you can not use interrupt mode.
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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