# How can I use the watchdog timer in interrupt mode?

I am using an atmega168 with avr-libc. Now, to form control loop of a fixed duration, I need a, say 1 second interrupt. Being clocked from an 8MHz clock, the only useful clock source seems to be he 128kHz watchdog oscillator.

The datasheet(page 49) hints that this is possible:

In interrupt mode, the WDT gives an interrupt when the timer expires. This interrupt can be used to wake the device from sleep-modes, and also as a general system timer.

However, the library reference makes no mention of operating modes. What now?

• Can the chip generate interrupts from timers? – W5VO Dec 18 '15 at 14:48

The watchdog oscillator is very inaccurate, and if you look at the datasheet you'll see that its frequency varies between 111 and 121kHz depending on both temperature and supply voltage.

So while you could set WDIE and implement WDT_vect, you're much better off using a timer for this. Especially if you're using a crystal or external clock with more accuracy than the internal RC oscillator.

• That's actually more accurate than my current clock of [7.3-8.1] MHz RC oscillator. – Vorac Dec 19 '15 at 4:13
• Unless you're working in a wide range of temperatures, it will be very close to 8MHz. And if it's not, you can tweak it with OSCCAL. The WDT will never be close to 128kHz. – Ignacio Vazquez-Abrams Dec 19 '15 at 5:11

If you want an interrupt every 1 second with an 8Mhz clock, probably the best way is to use a Timer1 in CTC mode with an appropriate prescaller and TOP value.

By using the clk/1024 prescaler, you lower the rate of the counter to 8KHz from 8Mhz. You select this this prescaller with these bits...

By using CTC mode, you tell the counter to reset every time it hits the TOP. Next you can select CTC mode with these bits...

Finally, we need to set the TOP value so that it will match at 1Hz. Here is the formula for calculating the frequency generated in CTC mode...

...where N is the prescaller (1024 in our case) and Fclk_I/O is the IO clock (8Mhz in our case). Note that this formula gives us the frequency of a square wave that will be output if the pin toggles on each match, so We actually want double the value to get the match rate. To do this, we can just multiply by 2 (or cross out the 2 in the denominator).

After a little algebra, we (should) get a value for TOP of 7999. This makes intuitive sense since it takes one clock cycle for the counter to reset after hitting top, so if we start at zero and count up to 7,999 clock we will need one more to get back to where we started.

In the CTC mode we selected above, the TOP is held in the OCR1A register, so we set this register to 7999.

Timer1 will now fire a match at 1Hz.

Finally, we just need to enable an interrupt routine to run on each match. The interrupt is controlled by the OCIE1A bit...

Once we set this bit, our ISP should be called at exactly 1Hz (depending on the accuracy of the 8Mhz clock the chip is running from).

• What puzzles me is why would avr-libc not have support for this. As is evident, they support most other features of atmega 48/88/168 and those are have been around for quite some time. – Vorac Dec 19 '15 at 4:14