How to use PIC's TMR2 module ?

Thread Starter

LETITROLL

Joined Oct 9, 2013
218
Hello there .

I have successfully accomplished TMR0 and TMR1 interrupts , but TMR2 is totally different in configuration , i don't understand how to set PR2 value for a fixed time .


So basically what i do when setting up TMR0/1 is using this equation :

Count = Fosc/(4*Prescaler*Fout*(2^timer bits - Timer count start )

So for example for 1 sec we have 1 hz as Fout , using a 16 MHz quartz and tmr0 ,and a prescaler of /128 , i end up with this equation :

count = 31250/(256 - TMR0 ) , after that i try to find out a count number that is close enough to an enteger to have exactly 1 second delay .

For that i play with the equation varying the timer count start until i find out the correct count number that will be used as variable in the interrupt program :

So if i take for example 31250/(256-110) i get a count of 214 overflows to accomplish a TMR0 flag , the TMR0 value is 110 then.


I don't know if i can use the same approach with TMR2 ??
 

Thread Starter

LETITROLL

Joined Oct 9, 2013
218
Thanks shteii01 . but i will be asked to do it manually , so understanding how to work with it is important .

Anu other suggestions are very welcome .
 

shteii01

Joined Feb 19, 2010
4,644
Thanks shteii01 . but i will be asked to do it manually , so understanding how to work with it is important .

Anu other suggestions are very welcome .
When I took my uC class, we used intel chip, so I am no PIC expert. My best advice:
* Go over the code that the website generate, it has notes that should help you understand.
* Read Microchip manuals and application notes, surely they have explanations and examples.
 

JohnInTX

Joined Jun 26, 2012
4,787
You can set up TMR2 manually like this (ref. 16F887 datasheet but most others are pretty close).

The basic input count to TMR2 is Tcyc which is the oscillator period / 4 i.e. with a 4MHz oscillator, TMR2 will increment at 1us per count. The first step is to calculate the number of Tcycs in the desired time for example at Tcyc=1us, a 10ms time gives 10ms/1us = 10,000 Tcyc that has to be counted.

Next, factor 10,000 to fit the pre/post scalers:
The prescaler is used to slow down the increment rate by 1:1, 1:4, 1:16. At the max prescaler, TMR2 increments at 16uS (for 4MHz). The prescaler is set by bits 1-0 in T2CON.

TMR2 is only 8 bits so it can count up to Tcyc * PreScaler * 256 uS.
While other timers count from some preset to rollover FFFF->0000, TMR2 counts from 0 to PR2 then resets to 0. Unlike the other timers, TMR2/PR2 runs its period automatically. The period is given by
(Tcyc * PreScaler * PR2).

The PostScaler counts the 0->PR2 rollovers and interrupts the PIC (when enabled) every 1 to 16 times depending on bits 6-3 of T2CON making the interrupt period Tcyc * PreScaler * PR2 *PostScaler.

To set it up, first determine the number of Tcyc that you need to time then factor that value into PreScaler, PostScaler and PR2 settings. It may take a few tries to get it but the general method is to rough it out with the pre/post scalers and tune with PR2. For the 10ms example PreScaler = 4, PostScaler=10, PR2=250 gets 4*10*250=10000 Tcyc

I use EXCEL where the formula is PR2 =(Fosc*Period1)/(PreScaler1*PostScaler1*4) and:
Fosc is the oscillator frequency (note the /4 later in the formula)
Period1 is the desired interrupt period in seconds
PreScaler and PostScaler are the settings in T2CON

Note that when you are determining the factors, PreScaler is the most coarse, set it first. Then set the PostScaler. Finally, fine-tune the timing with PR2. There will be several combinations that yield the same total count, try to make PR2 as large as possible for finest control over the timing. There will be times that you can't get exactly (because the total time is not an integer multiple of Tcyc). The only fix is to live with it or adjust the oscillator frequency.

That's about it.
 
Last edited:

THE_RB

Joined Feb 11, 2008
5,438
If you need to generate exact seconds, for clock use, this page has a lot of examples of how to do it using any timer and any xtal frequency;
http://romanblack.com/one_sec.htm

Some of the benefits of these systems is that they can be incorporated into existing timer interrupts (at any interrupt freq) and they can also be "fine tuned" down to parts per million to give accurate clocks by mathematically trimming out any small xtal freq error. :)
 

MaxHeadRoom

Joined Jul 18, 2013
28,698
I tend to use a 32Khz clock crystal to run T1 for real-time clock apps, then the code is transportable without concern for different system clocks etc.
Max.
 

THE_RB

Joined Feb 11, 2008
5,438
I just use ANY repetitive timer inteuupt that is going, and add this little code chunk into the interrupt;

Rich (BB code):
// C code for a 1 second period with a 1MHz timer (4MHz xtal);
// uses 1 variable; unsigned long bres
// gets here every TMR0 int (every 256 ticks)

  bres += 256;          // add 256 ticks to bresenham total

  if(bres >= 1000000)   // if reached 1 second!
  {
    bres -= 1000000;    // subtract 1 second, retain error
    do_1sec_event();    // update clock, etc
  }
For transortability all that is needed is that "magic number" 1000000 be changed to suit the new xtal speed.

Or coded more nicely to be a constant that refers to the xtal speed;

#define XTAL_FREQ 4000000
#define PERIOD1SEC (XTAL_FREQ / 4)
:)
 
Top