Electronic – arduino – Method to determine least-error prescaler and top values for timer1 of Arduino

algorithmarduinotimer

If this question should be in StackExchange instead of here I can delete here and post there.

Using an Arduino Duemilanove (Atmega328) I am trying to generate a square wave (50% duty cycle) of frequency somewhere between 500 Hz and 200 KHz, as entered by a user. I do not need any variable PWM duty cycle, just a simple square wave. Also I can not use Timer0 since modification of that affects delay() and other time related functions of the Arduino.

The timer calculations for prescaler and top counter have me very confused, can someone point me to an algorithm to identify which combination of prescaler and top values will give the closest output frequency to the specified one? In many cases, two or more combinations of prescaler and top give similar output frequency results but neither is exact.

For example user enters value of 98350 Hz. How would my Arduino code find out what prescaler and top counter value to set the Timer 2 registers to, for the closest match to that frequency?

Best Answer

The Arduino Playground Timer1 library does what you describe: Set Timer1 to whichever period (i.e. 1/f) is specified. You can either examine the code which is on GitHub to build your own version, or use the library directly.

If using Timer1 directly, these lines will generate the 50% duty cycle square wave required:

#include <TimerOne.h>

setup() {
    pinMode(squareOut, OUTPUT);    // squareOut can be either 9 or 10 on Duemilanove
    Timer1.initialize();
    // Other set-up code
}

setFrequency(frequency) {
    Timer1.pwm(squareout, 512, (long) 1000000L / frequency); // Duty cycle = 0-1023
}

The library uses the method described by @JimParis in the answer above, to determine the prescaler and Top values within TimerOne::setPeriod.

If you generate a more optimized version of that bit of code from the library, please share, as I would like to use it.