Pic Timer 0 Timer 1 tutorial?

Thread Starter

spinnaker

Joined Oct 29, 2009
7,830
Can anyone point me to a easy to understand tutorial on how to calculate values for timer 0 and timer 1 for the Pic?

I have always used calculators and I think it is time to understand how to do it myself.

In case anyone wants to provide a step by step please use the following for the example. I need to set timer 1 for 32,768 (yeah I know I might not get it exactly) with an 8MHZ clock.
 

ErnieM

Joined Apr 24, 2011
8,377
Timer1 is just a 16 bit counter. When it rolls over from 0xFFFF to 0x0 it sets a flag that may be used to trigger an interrupt.

Using that clock, as 8 MHz / 32,768 = 244.140625, which is a non integer, you cannot get that exact frequency. The closest you could ever get is 32786.885 or 33057.851, and to get either Timer2 would be a much better choice.
 

thatoneguy

Joined Feb 19, 2009
6,359
What you can do is preload the timer with a value before an interrupt to reduce error, but getting exactly 32768 Hz would require a lot of overhead, as well as jitter in the output.
 

t06afre

Joined May 11, 2009
5,934
32768 are equal to 0x0800. You will not get any jitter if you in your software are able to write 0x80 to the TMR1H register before TMR1L reach the value 255. This trick is often used in digital clocks applications. But then a clock crystal 32768 Hz is often used to drive timer1
 

thatoneguy

Joined Feb 19, 2009
6,359
32768 are equal to 0x0800. You will not get any jitter if you in your software are able to write 0x80 to the TMR1H register before TMR1L reach the value 255. This trick is often used in digital clocks applications. But then a clock crystal 32768 Hz is often used to drive timer1
DOH. Thought he was using the 8 bit timer.
 

t06afre

Joined May 11, 2009
5,934
Some PIC MCU also have timers that can be compared to a value in some special purpose register(s). The timer value are equal to the compare value. The timer is reset and an interrupt can be generated. I think the correct term for this is CCP modules (Capture/Compare/Pwm).
 

ErnieM

Joined Apr 24, 2011
8,377
Some PIC MCU also have timers that can be compared to a value in some special purpose register(s). The timer value are equal to the compare value. The timer is reset and an interrupt can be generated. I think the correct term for this is CCP modules (Capture/Compare/Pwm).
The correct term is "Timer2" using the PR2 compare register. This still leaves the problem of a non integer divisor to get 32768 out of 8,000,000.

One may be able to get close to an "average" rate of the desired frequency but never that exact rate.

If a crystal that is an integer multiple of 32768 can be found then the rate could be obtained. Both a 6.55360 MHz (divide by 20) and a 8.192 MHz (divide by 25) crystals are available, though the latter may be into the "hot clocking" range for that device.

These can yeild that frequency precisely via Timer2. Timer0 or Timer1 are both unsuitable for an exact frequency (though you may get very close).
 

t06afre

Joined May 11, 2009
5,934
The correct term is "Timer2" using the PR2 compare register
You have PICs in the 18F series with up to 10 timers. So this will depend heavily on which PIC we are discussing. But most often on more standard/common PICs this function this function are to be found on timer2. That is correct. As an aside. As I understand the request from Spinnaker. He want to a pic counter start counting from 0x8000 on each itteration. If he want to generate a 32768 Hz frequency. My advice will not be very good
 
Last edited:

Thread Starter

spinnaker

Joined Oct 29, 2009
7,830
Thanks guys but first I want to know how to preform the calculation to set a specific clock frequency.

And yes I can have an external crystal osc and I will but want to use the internal RC osc for now but still need to know how to do the calculations in general.

Is it just divide the clock by 4, divide that by your prescaler divider, you then get the amount of time per "tick", divide the time you need by that time and that is the value you load into your registers?
 

ErnieM

Joined Apr 24, 2011
8,377
Is it just divide the clock by 4, divide that by your prescaler divider, you then get the amount of time per "tick", divide the time you need by that time and that is the value you load into your registers?
That pretty much covers it for Timer2. You also have a post scaler to play with I believe.
 

Thread Starter

spinnaker

Joined Oct 29, 2009
7,830
That pretty much covers it for Timer2. You also have a post scaler to play with I believe.
Actually it is timer 1 I am working with now and I must be missing something.

OK I have an 8MHZ clock.

For the timer that is 8MHZ / 4 or 2MHZ.

That makes for a period of .5us.

I need a clock of 32,768 HZ or a period of 30.5 us.


30.5 / .5 = 61.

That does not sound right. What am I missing?

Do I subtract this number from 65,535?

If so why?
 

thatoneguy

Joined Feb 19, 2009
6,359
If it doesn't need >255 cycles, you can use an 8 bit timer.

In the timer interrupt, preload timer with 255-61, then exit interrupt, it will come back to the interrupt in 61 timer ticks.
 

ErnieM

Joined Apr 24, 2011
8,377
Actually it is timer 1 I am working with now and I must be missing something.

OK I have an 8MHZ clock.

For the timer that is 8MHZ / 4 or 2MHZ.

That makes for a period of .5us.

I need a clock of 32,768 HZ or a period of 30.5 us.


30.5 / .5 = 61.

That does not sound right. What am I missing?

Do I subtract this number from 65,535?

If so why?
You are missing the inability of Timer1 to perform this action.

With an instruction clock running at 8 ÷ 4 = 2 MHz you desire a 32,768 Hz output. Dividing we get:

2 MHz ÷ 32,768 = 61.03515625

Note this is NOT 61 as you state, so your frequency will be off.

Now the even sadder part. Timer1 cannot divide by 61, no less 61.03515625.

The best you can do is get "sort of" close. And as this requires an interrupt routine there may be an ambiguity in exactly how long it runs. It may vary by at least 1 clock cycle. (It may not as the trigger is synchronous to the instruction clock). But you can try this:

1) Set up an interrupt routine with Timer1 overflow as a trigger

2) Load Timer1 with 255 - 61 = 194 = 0xC2

3) After 61 instruction cycles Timer1 overflows, the interrupt triggers, and you get into the handler. The entry into the ISR is your "Tick."

4) Load 0xC2 back into Timer1 for the next Tick.

5) Run the code in the MPLAB simulator over and over as the 0xC2 value will need to be tweaked to account for the few instructions the ISR needs.

Note if you use Timer2 as I have said then the timer would automatically update itself and at least give you a stable (÷ 61) frequency division.
 

Thread Starter

spinnaker

Joined Oct 29, 2009
7,830
You are missing the inability of Timer1 to perform this action.

With an instruction clock running at 8 ÷ 4 = 2 MHz you desire a 32,768 Hz output. Dividing we get:

2 MHz ÷ 32,768 = 61.03515625

Note this is NOT 61 as you state, so your frequency will be off.

Now the even sadder part. Timer1 cannot divide by 61, no less 61.03515625.

The best you can do is get "sort of" close. And as this requires an interrupt routine there may be an ambiguity in exactly how long it runs. It may vary by at least 1 clock cycle. (It may not as the trigger is synchronous to the instruction clock). But you can try this:

1) Set up an interrupt routine with Timer1 overflow as a trigger

2) Load Timer1 with 255 - 61 = 194 = 0xC2

3) After 61 instruction cycles Timer1 overflows, the interrupt triggers, and you get into the handler. The entry into the ISR is your "Tick."

4) Load 0xC2 back into Timer1 for the next Tick.

5) Run the code in the MPLAB simulator over and over as the 0xC2 value will need to be tweaked to account for the few instructions the ISR needs.

Note if you use Timer2 as I have said then the timer would automatically update itself and at least give you a stable (÷ 61) frequency division.
OK now you have me really confused. Timer 1 is a 16 bit timer. Why do I need to do this?

And my question still stands. Why do I subtract the number I get from 65,535 or 255 (or whatever)? Just why do I need to subtract to get the number I need?
 

ErnieM

Joined Apr 24, 2011
8,377
OK, Timer0 is 8 nit, Timer1 is 16 bit, but the same theory applies.

The timer generates an interrupt when it rolls over from 0xFFFF to 0x0000. So to get a delay of N you load the timer register with (0xFFFF - N).
 

Thread Starter

spinnaker

Joined Oct 29, 2009
7,830
OK I get it. It counts backward!


So I understand how the presacler works into the formula. Now how does the postscaler work?
 

ErnieM

Joined Apr 24, 2011
8,377
OK I get it. It counts backward!


So I understand how the presacler works into the formula. Now how does the postscaler work?
LOL, no it does not. It counts UP, always UP.

Take an 8 bit timer. It normally counts 256 times (0 to 255) over and over. When it has reached 255 and then clock changes it to 0 then the interrupt fires.

If you want it to happen faster then 256 then you can preload a value so it doesn't start counting at 0, but at your preset value.

So to get the timer to give interrupts at a rate of 10 instead of 256 you preload with 256-10 so it only takes 10 counts to roll over.

Oops, the post scaler doesn't exist on Timer 0 or 1, it's there on Timer 2. It works just like the prescaler by dividing the output pulse train.
 
Top