# PIC Microcontroller timer

We want to be able to design a PIC microcontroller based timer. The specification requires that we have a time for at least one month (30 days). I have been trying to figure out how one can do that but I am stuck. Any suggestions please?

• how accurate? [gratuitous blather because stackexchange has bureaucratic quality filters] – Jason S Apr 7 '12 at 1:55
• What PIC microcontroller? – m.Alin Apr 7 '12 at 11:23
• Is there a possibility in the future that this time period may change? – abdullah kahraman Apr 7 '12 at 11:25
• The accuracy of the timer is very irrelevant. We can tolerate up to two days per month. – hikimoto Apr 8 '12 at 7:12

How accurate does this 30 day period have to be? 30 days is about 2.5 million seconds, with a crystal accuracy of 20 ppm you might have a one minute error after 1 month.

If a one minute error is unacceptable you could use a temperature controlled oscillator or a better crystal, like 5 ppm. If external aid is allowed you could use the signal of a DCF77 receiver (Europe, WWVB for North-America). These will give you a tick per second with atomic clock precision. All you have to do is count pulses. Note that DCF77 has only 59 pulses per minute, the omitted pulse indicates the start of a new minute. If you take this into account your 30 day period has elapsed after 2 548 800 pulses (59 $\times$ 60 $\times$ 24 $\times$ 30).

If the PIC has to do it all by itself that shouldn't be a problem either. Clock at 32768 Hz and program a timer to give an interrupt after 32768 clock cycles, that's one second. Count 2 592 000 interrupts (60 $\times$ 60 $\times$ 24 $\times$ 30).

In a month a lot can happen, and you probably want a battery backup in case there's a power outage. If you use the atomic clock signal you can also decode the time code after each minute pulse and compare date and time with your target time. In that case power outages don't even matter.

edit
You don't mention which PIC you're using, and without any practical experience with them I know there is a lot of them. I'll pick the PIC10F200 because as I understand it it's (one of the) least capable PICs, just having one 8-bit timer/counter.
The timer/counter can be clocked internally by the clock/4, and has a selectable prescaler. If you use a 32.768 kHz crystal for the clock, then clock/4 = 8192 Hz. Set the prescaler to $\div$32 and the 8-bit timer/counter will overflow once every second.

edit 2 (re Olin's comment)
Olin points out that the PIC10F200 only has an internal oscillator. That won't have crystal accuracy, but you can clock the timer from an external clock. Connect the output of the 32.768 kHz oscillator to the T0CKI input and set the prescaler to $\div$128. Then the 8-bit timer/counter will overflow once every second. As I understand it there's no overflow interrupt, so you'll have to detect this by comparing the timer value to 0x00.

edit 3 (re your comment on accuracy)
Allowing a two day error in one month is what we call very low accuracy. That 6.7%. The internal oscillator is calibrated to 1% at 25°C, 2% over the full range. So if you want you can use the internal oscillator, then you don't need the external 32.768kHz crystal. The oscillator is tuned to 4MHz, $\div$4 gives you 1MHz at the timer's prescaler. If you set the prescaler to $\div$64 then the 8-bit timer is clocked at 15625Hz. Count 61 overflows for every second, even if you ignore the remainder you still get 0.06% accuracy.

• The 10F PICs don't have the capability of running a external oscillator. They have a internal oscillator that the instruction clock is derived from. That is good to a few percent over temperature and voltage. If that's good enough accuracy, then a 10F200 can do this job. That means you need a single SOT-23 package and a bypass cap. – Olin Lathrop Apr 7 '12 at 14:58

PICs don't have oscillators with 30 day periods built in, but you can very easily make one from a faster oscillator by counting cycles. You start with a faster clock you do have available, like the instruction clock or a external timer 1 oscillator. You can use a timer to reduce this clock to a low enough frequency so that it is reasonable to interrupt on it or even just poll for a new cycle in the foreground code.

For example, you can easily generate periods of 1000s of instruction cycles using timer 2 and its dedicated period register, prescaler, and postscaler. You didn't say what PIC you had in mind, so I'll assume a normal PIC 16 or PIC 18. You use a counter in RAM you manage from firmware to divide the rest of the way. For example, if the PIC will be doing other things, it's often convenient to set up a periodic 1 ms interrupt using timer 2. The interrupt routine could generate multiple ticks, like 10 ms, 100 ms, and 1 second, 1 minute, 1 hour, and 1 day. Then you count 30 1-day ticks. This method requires only a single byte for each divider in the chain and makes sense when the other ticks are useful too. If the other ticks are of no use, you could just count 2,592,000,000 millisecond ticks, which requires 4 bytes.

If low power is important and the PIC can sleep a good fraction of the time during the 30 days, then connect a 32768 Hz watch crystal to timer 1 and have the PIC wake up every 2 seconds when the timer overflows. Count 1,296,000 timer 1 overflows to get 30 days. That requires 21 bits, so only 3 bytes of RAM.

There is another solution. Some PICs include a real-time-clock-calendar (RTCC) feature. To see which ones support this, click the link then check "Hardware RTCC" on the right. http://www.microchip.com/maps/microcontroller.aspx

This chart quickly and easily (when sorted by pin count and looking near the bottom) reveals that the 18F24J11 should be small, robust, inexpensive, and comes in QFN, SOIC, SPDIP, SSOP (28) packages.

In PICs with RTCC, you set the current date and time, then set an alarm date and time, and put it to sleep. Periods ranging from fractions of a second to centuries are possible. It can then wake itself up upon RTCC alarm interrupt. Some models use very little current while asleep (with the RTCC module still running.)