Electronic – Writing to timer counter while timer is running

best practiceinterruptsmicrocontrollerpictimer

I'm using PIC16F1947 for a project. The project requires real time tracking so a stable 32768 Hz crystal is connected with the Timer1 oscillator. The Timer1 oscillator circuit and the crystal will provide stable clock for our project.

Timer1 can only provide interrupt when the timer counter overflows. It is a 16 bit counter so interrupt will be given each time the counter rolls over to 0x0000 from 0xFFFF.

Since the timer will be used for time keeping purpose from the beginning to the end of the product, Timer1 can't be stopped. Also, it has to be run while the processor is sleeping. So we need to use it in asynchronous mode.

In our project we also need interrupts every 0.5 second. So we plan to initialize Timer1 counter to 0xC000 and then start it. Each time an interrupt will be given, we plan to bitwise OR 0xC0 to the high byte of the register.

According to the datasheet:

Reading TMR1H or TMR1L while the timer
is running from an external
asynchronous clock will ensure a valid
read (taken care of in hardware).
However, the user should keep in mind
that reading the 16-bit timer in two
8-bit values itself, poses certain
problems, since the timer may overflow
between the reads.

For writes, it is
recommended that the user simply stop
the timer and write the desired
values. A write contention may occur
by writing to the timer registers,
while the register is incrementing.
This may produce an unpredictable
value in the TMR1H:TMR1L register
pair.

Is it OK to bitwise OR 0xC0 with the high byte while the timer is running? Or should we use another Timer for 0.5 second interrupt?

Thanks.

Best Answer

On the PICs with two 32KHz timers (TMR1 and TMR3) my recommendation would be to use one of the timers 'free-running' (never write to it) and use the other to generate wakeup events. If you only have one timer available, getting reliable operation without cumulative errors is going to be very difficult. Different part revisions have different behaviors when it comes to writing timer 1, and so an approach that would work with one revision may be broken by a future revision. What would have been nice would have been if Microchip had allowed the timer to switch between synchronous and asynchronous modes without losing a count (simple to do: instead of using a multiplexer to switch between sync and async mode, add asynchronous set/clear to the synchronizing latch, and when in async mode use those to force the output to follow the input). None of their parts are, so far as I know, documented as doing any such thing. Consequently, I would expect that switching between synchronous and async mode may randomly gain or lose a count.