AVR watchdog reset timer-practical approach

This is a continuing thread. Why use a watchdog variable timer. This post is about how the watchdog timer on the AVR microcontroller works and how to control it.

As we mentioned earlier, the watchdog timer is a distinct timer counter, which generates a reset signal when it fills up.

After the watchdog timer counts up to maximum, it generates a short pulse duration of 1 clock cycle. This pulse triggers an internal reset timer counting up to tout.

AVR watchdog timer is a distinct clock generator that runs at 1 MHz. Watchdog timer has a Prescaler module. So the reset interval can be selected by adjusting the Prescaler. Generally, there are three things you have to do while controlling the watchdog timer: enable, disable, and set Prescaler.

First of all, we need to set a watchdog timer Prescaler. Prescaler settings can be set in WDTCR(Watchdog Timer Control Register) register(Atmega8).

Prescaler is set by setting three bits (WDP2, WDP1, WDP0) of the WDTCR register(see table below):

To be able to control the watchdog timer, there some logic that needs to be preserved.

To enable the watchdog timer, just set the WDE bit in WDTCR. Disabling and setting prescaller is more complicated because some sequence of operations has to be made.

Write “1 to WDCE and WDE at the same instruction cycle (WDE must be written to”1 regardless if this was set earlier);

Within the next four cycles, write logical “0” to WDE. This disables the watchdog timer.

Setting timer prescaller uses the same operation sequence:

Write “1” to WDCE and WDE at the same instruction cycle (WDE must be written to “1” regardless if this was set earlier);

Within the next four cycles write WDP bits in the WDTCR register. This sets new prescaller values of the watchdog timer. Don’t write 0 to WDE as this will disable the timer.

ASM example:

ldi r16, 0x18
out WDTCR, r16 ;set WDTOE and WDE
ldi r16, 0x10
out WDTCR, r16 ; write a 0 to WD

and C example:

void WDT_off(void)
{
/* reset WDT */
_WDR();
/* Write logical one to WDCE and WDE */
WDTCR |= (1<<
/* Turn off WDT */
WDTCR = 0x00;
}

Watchdog timer can be enabled during flashing the chip.

Example from PonyProg programming software. Uncheck WDTON bit to enable watchdog timer. Prescaler can be changed (or watchdog timer disabled) the same way as discussed earlier. You cannot disable the Watchdog timer this way (this can be done only by changing fuse settings).

Note: before you enable the watchdog timer, always reset the watchdog timer because the value might be non-zero left. To reset the timer, use standard AVR assembler instruction WDR.

If you use the WinAVR toolset, watchdog timer control can be much easier as there is a pre-maid library for controlling the watchdog timer.

Include wdt.h header from AVR folder (#include “avr/wdt.h”)

You may use functions:

#define wdt_reset()
#define wdt_disable()
#define wdt_enable(timeout)

Timeout values are also predefined:

#define WDTO_15MS 0
#define WDTO_30MS 1
#define WDTO_60MS 2
#define WDTO_120MS 3
#define WDTO_250MS 4
#define WDTO_500MS 5
#define WDTO_1S 6
#define WDTO_2S 7
#define WDTO_4S 8
#define WDTO_8S 9

Some timeout values may differ in different MCU types. Refer to AVRlibc documentation.

Leave a Reply