CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug Reports on this forum. Send them to support@ccsinfo.com

Timers - what you should know

 
Post new topic   Reply to topic    CCS Forum Index -> Code Library
View previous topic :: View next topic  
Author Message
newguy



Joined: 24 Jun 2004
Posts: 1517
Location: Edmonton, Alberta

View user's profile Send private message

Timers - what you should know
PostPosted: Wed Apr 06, 2005 9:24 am     Reply with quote

Reposted from the other forum.... I figured it would be useful to have it here too.

Hopefully this helps to clear up some of the confusion regarding timers. I will use an example that is driven by the internal (system) clock.

Whatever the master crystal frequency is, the internal (system) clock is always the crystal frequency divided by 4.

Example:

Crystal: 4 MHz
System clock: 1 MHz (1 microsecond period)

The system clock is what drives the timer modules (if set up to use the internal clock.) However, there is a prescaler which can also be set. A prescaler is a programmable "divide by N" block where N is the number of input clock cycles it takes to get one output cycle out of the prescaler.

Example:

Let's assume that you want to use timer 0. Timer 0's prescaler can be set to 1 (no divide at all), 2, 4, 8, ....., all the way up to 256. If it was set to 256, then it would take 256 system clock cycles to get one cycle out of the prescaler. Therefore timer 0 would then count up at a rate of one count every 1 microsecond (system clock) x 256 (prescaler setting) = 256 microseconds/count.

Note that some timers can also have postscalers.

A timer will generate an interrupt every time it overflows, and if its' interrupt is enabled. Timer 0 can be set to either 8 bit mode or 16. In 8 bit mode, it overflows every 256 counts. It would take 65,536 counts in 16 bit mode.

To completely set up timer 0 in 8 bit mode with the system clock as its source and with a prescaler of 256, you would code:

Code:
setup_timer_0(RTCC_INTERNAL|RTCC_8_BIT|RTCC_DIV_256);


The constants used in this function, and the functions for the other timers are found in the device's header file. For instance, 18F452.h. Look for it in the PICC\devices directory.

Extending our example:

In 8 bit mode, timer 0 would overflow (interrupt) every 256 microseconds/count x 256 counts/overflow = 65,536 microseconds = 65.536 milliseconds.
In 16 bit mode, timer 0 would overflow (interrupt) every 256 microseconds/count x 65,536 counts/overflow = 16,777,216 microseconds = 16.777216 seconds.

So, with all this in mind, it's up to you to choose
a) the clock source,
b) whether you need an 8 or 16 bit counter, and
c) the prescaler value.

So, as a starting point, if I had to create a 1 ms "tick" and my crystal frequency was 4 MHz, I would do it this way (again as a starting point; greater accuracy may require different values).

Timer 0: 8 bit mode, driven by the internal clock. Now the (harder) part: choosing the prescale value.

If the prescaler was set to 1, I'd get an interrupt every 256 us. This is probably too fast - I wouldn't want to tie up the processor with all of the interrupt services this would take - about 4 per millisecond.

If the prescaler was set to 2, there would be an interrupt every 512 us. Again, probably too fast.

If the prescaler was set to 4, there would be an interrupt every 1,024 us = 1.024 ms. Bingo. If timing isn't absolutely critical, I'd just let timer 0 free run. If timing is critical, then you'll need to tweak this just a bit.

With the prescaler set to 4, timer 0 counts up once every 4 us. So how many 4 us clicks are in 1 ms? 0.001s/0.000004s = 250. This is the number of counts of timer 0 in 1 ms (note that 250 is 6 less than 256 - this will be important later). Aha. Now we have everything we need.

Timer 0's ISR:

Code:
#byte timer0low = 0xfd6

#int_RTCC
void RTCC_isr(void) {
timer0low = timer0low + 6;
one_millisecond = TRUE;
}


All you look for in the main routine is for one_millisecond to be set. There's your 1ms tick.

The reason why I directly add 6 to whatever timer 0's count is at is because 6 is the number of ticks I need to skip in order for timer 0 to count 250 times before it rolls over. If used:

Code:
set_timer0(6);


instead, the accuracy of the 1 ms tick would be very poor. That is because it takes quite a long time for the processor to stop what it is doing and service the interrupt. With a 4 MHz clock, this may be 60 - 80 us or more. By the time that the processor gets around to servicing the interrupt, timer 0 will have counted up to 15 - 20 already; by setting it back to 6, what we think is our 1 ms tick will be way too slow.

And the location of timer 0's register is found in the PIC's data sheet. Look in the memory organization section for the special function registers. You'll find all of their memory addresses there.

Lastly, EXPERIMENT FOR GOD'S SAKE!!!! It is so annoying seeing weekly pleas for help to get a certain clock tick. EXPERIMENT!!!! How do you think that the experienced people here got that way? Hook up an led and flash the stupid thing at an easily measurable/discernable rate so you can confirm your calculations. Setting up a timer isn't rocket science.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> Code Library All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group