Calculating Microcontroller Timer Parameters

November 02, 2012
Home

Recently I was working on a project involving an ARM processor and a Bluetooth module which required a clock signal at 32.768 kHz. To avoid adding an external oscillator, we tried to use the ARM processor as a clock source. The clock speed on the ARM was 72 MHz, with a user specified 16 bit pre-scaler and 16 bit compare register. To determine what pre-scaler and compare values could be used to get closest to the required frequency, I wrote the following small program:

/*
 * Finds prescaler and compare register values that result in an output closest
 * to a goal frequency via brute force.
 */
#include <stdio.h>
#include <math.h>
int main(int argc, const char *argv[]) {
	unsigned int clock = 72000000;
	unsigned int prescaler;
	unsigned int compare;
	double goal = 32768;
	double i;
	double min = 100;
	for (prescaler = 1; prescaler <= 65536; prescaler++) {
		for (compare = 1; compare <= 65536; compare++) {
			i = (clock / prescaler) / compare;
			if (fabs(goal - i) <= min) {
				min = fabs(goal - i);
				printf("prescaler: %d, compare: %d, freq: %f\n", prescaler, compare, i);
			}
		}
	}
	return 0;
}

In less than 20 seconds, it found out that with a prescaler of 2197 and a compare value of 1, the output frequency would be 32881 Hz. Unfortunately that was not within the tolerances of the bluetooth module, so an external oscillator was added to the schematic.