Blog moved to

Monday, 5 January 2015

Accurate clock with any frequency oscillator (e.g. embedded PIC projects)

When I created an electric timer using a PIC one of the things I needed was an accurate clock. The PIC I was using did not have a built in real-time clock (RTC) and I did not want to use an external one. After some searching I found two popular suggestions to create an accurate clock
  1. Use a 32.768kHz crystal which divides down perfectly to give you seconds etc
  2. Use any frequency oscillator and manually set the value of the timer register on each interrupt. I.e. to skip some number of cycles
I did not like either of these solutions
  1. 32.768kHz is ridiculously slow compared to the 20-40MHz the PICs can run at
  2. Manually setting the timer register takes some number of clock cycles and this will affect the timing. Working out how many clock cycles exactly sounds like an error prone and rather boring task
Fortunately I found this article "A very versatile Zero Cumulative Error timing system with PIC source code" @ It shows a really simple way to get an accurate clock, i.e. no accumulating error,using any oscillator frequency. Take a look at the article. It has PIC source code and a nice explanation.
Its a brilliantly simple solution. Here is my attempt to explain it. Perhaps having two different explanations helps.
Imagine you have an oscillator that ticks every 3 units but a clock event that needs to happen every 5 units of time. The key to understanding this is that even though 3 does not go into 5 you can get close without accumulating error.
Consider the first 5 oscillator ticks
  • 3 - less that first time period (5), do nothing
  • 6 - greater that first time period (5), do clock
  • 9 - less that second time period (10), do nothing
  • 12 - greater that second time period (10), do clock
  • 15 - equal to third time period (15), do clock
So at each oscillator tick there is some discrepancy but it does not accumulate. In the example above the clock is 100% accurate every fifteenth oscillation.
With a micro running at many megahertz you can adjust the timer prescale to make this periodic discrepancy as small or large as you like.
In my timer I was happy to be out by a few seconds at any time. Of course you could of course use a smaller prescale value and keep it down to milliseconds if you really need to