[Josh] has written up two posts that those of you who use AVRs might find handy. The first post documents a C library that implements a jitter-free one-shot timer. The second post explains how it works. We think it’s such a good idea that we’re going to spoil it for you, but go ahead and read his links and check out his code.
A one-shot is a pulse generator that runs once and only once. You trigger it, it produces the desired pulse, and that’s all she wrote. Why is this handy? Many external ICs that you’ll interface with have minimum durations for signal pulses that must be respected. You could program the AVR to toggle a pin high and then sit around and wait until it’s time to toggle the pin low again, but this wastes valuable CPU time, isn’t going to be very precise, and is susceptible to timing discrepancies if interrupt routines fire in the mean time.
You’d think that you could use the hardware timers for this, but it’s not straightforward. Normally, the timers are free-running; the counter that’s keeping track of time rolls over the top and starts over again. But we just want one pulse.
[Josh]’s very clever idea abuses the timer/counter’s TOP and MATCH values in “Fast PWM” mode. Essentially you trick the counter into never matching by setting TOP below MATCH. This means that the counter spins in its loop between zero and TOP forever, doing nothing.
To break it out of its loop and enable the one-shot, you manually set the counter to a value above TOP and let it go. As it counts up, it’ll eventually hit MATCH, turn on your pin, and then keep counting. When it rolls over the top (255 + 1 = 0 for the 8-bit AVRs), your pin will be correctly turned off again and then the counter re-enters its loop. The one-shot won’t fire until you manually set the counter higher than TOP again.
So there you have it, a one-shot depending only on the hardware timer/counter module and thus immune to jitter and consuming no CPU time at all. Our hats off to you, [Josh]. Clever hack.