Monday, July 9, 2012

Timers and Comparators

I've learnt a couple of interesting things over the last couple of days fighting with why my drivers didn't seem to be working.  What I found was that I was unable to modify OCR1A while the timer was running, or rather, I was able to modify it, but only once per timer cycle.

The reason for this appears to be due to a mechanism the chip uses to update the OCR1A register called double buffering.

The chips documentation had this to say about it.

"The double buffering synchronizes the update of the OCR1x Compare Register to either TOP or BOTTOM of the counting sequence. The synchronization prevents the occurrence of odd-length, non-symmetrical PWM pulses, thereby making the output glitch-free."

So you can set OCRnA as often as you want, but it will only actually be set when the timer reaches 0.  This is highly problematic as changing OCRnA on the fly is essential to achieve the pin output complexities I am looking for.

This table from the documentation shows all the timer modes.


The only modes that update the comparators immediately are normal mode and CTC mode.  Normal mode is out as it always counts from BOTTOM to MAX and doesn't allow us to set the timer to 20us.

CTC could work, but it means that overflow can't be used.  What a pain.

I'm now in the process of rewriting the drivers to use CTC mode timer instead.  I'll likely post the resulting code on GitHub.

EDIT:  Sooo, after all that I wound up using Normal mode.  I use OCR1B to change between triggering at 2600, and 19999.  When the 19999 trigger happens I call what used to be the overflow_interrupt function, and reset the timer to 0.  Seems to work ok.

No comments:

Post a Comment