Did you know an 8-bit Arduino Timer can output two frequencies simultaneously? When developing RTM_TimerCalc, I stumbled onto this. Here's a snapshot of the app showing the two frequency effect.
Arduino Timer Size and Mode
Arduino Nano, Uno and Mega2560 use similar Timer architecture. They have Timers of 8-bit and 16-bit count sizes. Both sizes have fixed and variable counting modes.
With fixed modes, we get only a few output frequencies based on Prescale selection and Clock-input. But we do get the full number of PWM output channels in the bargain.
However, if we want a variable frequency Timer mode, we may lose a PWM output channel. This happens when an output Compare register is used to hold a divide-by-N argument for the Timer. If the register holds N, then it can't be used for waveform generation. We lose that PWM output. On the plus side, we do realize a larger range of output frequencies.
Arduino Nano, Uno and 2560 MCU's all carry 8-bit and 16-bit Timers. The 16's have an extra register known as Input-Capture. Now, because Input-Capture is not needed for PWM generation, it can hold the N-divider value. That frees up an extra PWM channel.
But the 8-bit Timer has no Capture register. If we set it to have variable frequency capability, we tie up an Output-Compare register. That costs us a PWM channel.
With the 8-bit Timer, we either have 2 PWM channels (running at some fixed frequency) or a variable frequency on just one PWM channel.
However, Atmel put in a Toggle mode for the Output-Compare waveform generator. Our lost PWM channel can auto-generate a half-frequency square wave when this mode is set! That means our 8-bit Timer can create 2 frequency outputs! One frequency for PWM and a 50% (half-frequency) square wave on the lost PWM channel.
The next image shows the Toggle output (upper trace) and the PWM output below.
And here's example Arduino Code to make this happen in your project;
// generated by: RTM_TimerCalc -- RuntimeMicro.com // Timer2 Mode_7_8Bit_Fast_TOP_is_OCRa TCCR2A = 0x63; // 0110 0011 TCCR2B = 0x08 | 4; // Prescale=64 OCR2A = 250-1; // TOP OCR2B = (byte) (OCR2A * 0.5); // <-- Duty Cycle control for PWM // UnComment following lines for UNO-NANO Timer-2 Pins // pinMode(11, OUTPUT); // OC2a // pinMode(3, OUTPUT); // OC2b // UnComment following lines for 2560 Timer-2 Pins // pinMode(10, OUTPUT); // OC2a // pinMode(9, OUTPUT); // OC2b
What Good Is Two Frequency Output?
It might seem like we need an explanation why Atmel did things this way. There could be dozens of clever uses for that extra Square wave. I can't think of any right now :).
The good news is we know about it. We can turn it on and off as needed. And save it in our bag of Arduino Timer tricks for a rainy day.
Lee
Created: Feb 2, 2020 Updated: Jan 11, 2024 |