Environment
I am using an Arduino Mega 2560, here is the source code:
#ifndef F_CPU
#define F_CPU 16000000L
#endif
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/wdt.h>
void start_system_timer(void)
{
cli();
// Avoid eternal loop of time-out resets by clearing WDRF
MCUSR &= ~(1<<WDRF);
// Reset watchdog timer
wdt_reset();
// Enable WD timer configuration mode
WDTCSR |= 1 << WDCE | 1 << WDE;
// Reset WD timer
WDTCSR = 0;
// Configure period
wdt_enable(WDTO_1S);
// Use WD timer in interrupt mode
WDTCSR |= 1 << WDIE;
sei();
}
int main(void)
{
// Define digital pin PORTB7 as an output and turn on the led
DDRB |= (1<<PB7);
PORTB |= (1<<PB7);
start_system_timer();
sei();
while (1)
{
}
}
ISR (WDT_vect, ISR_NAKED)
{
// Turn off LED
PORTB &= ~(1<<PB7);
// Re-enable watchdog timer interrupt to avoid reset
WDTCSR |= 1 << WDIE;
reti();
}
Question
If I set watchdog timer to operate in interrupt mode and I don't reset the timer inside the interrupt handler then it resets the board.
According to the datasheet if it is on reset mode it should not go to system reset mode.
Also tried to clear WDIE
bit after setting interrupt mode using WDTCSR &= ~(1<<WDIE);
, just in case was set to 1 but didnt work either.
CodePudding user response:
I had that problem before. My mistake was setting the WDTON fuse bit. I thought its purpose was to "turn on the watchdog" (Watch Dog Timer On). But in reality, it forces the the timer to interrupt mode, no matter what bits you use in WDE and WDIE. Use a
Edit: WDTON written to 1 is disabled 0 is enabled! So you need to write it to 1
Edit2: As AterLux said, refer to this post for using reti().
CodePudding user response:
According to datasheet:
If WDE is set, the Watchdog Timer is in Interrupt and System Reset Mode. The first time-out in the Watchdog Timer will set WDIF. Executing the corresponding interrupt vector will clear WDIE and WDIF automatically by hardware (the Watchdog goes to System Reset Mode).
So after each interrupt changes mode to System Reset Mode and that's why needs to be re-enabled using WDTCSR |= 1 << WDIE;
.