|
|
View previous topic :: View next topic |
Author |
Message |
Freddie L Guest
|
Using TIMER0 on 16F84 |
Posted: Tue Feb 18, 2003 1:02 pm |
|
|
I'm using TIMER0 for the first time and need some help understanding how TIMER0 is setup and the PCM TIMER0 calls. I'm finding the CCS Manual (August 2002) and the example program ex_stwt.c lacking.
I need to keep track of time since a certain event occurred. I thought that I could setup TIMER0 to roll over every 2ms and use an Interrupt Routine to increment a counter each time the timer rolls over, this way a 1byte counter variable could keep track of 510ms. (pretty standard from what I've read)
I put together the following code from other posts. I'm not sure exactly what the setup_timer_0() and set_timer() commands are doing and how to calculate the correct passed values for 10Mhz clock, 2ms rollover etc... If someone could point me to a tutorial or provide a simple commented snip of code I would greatly appreciate it. (I've read the manuals but I'm still confused. A good example would straighten me out.) Thanks.
disable_interrupts ( GLOBAL );
enable_interrupts (INT_RTCC);
setup_timer_0 ( RTCC_DIV_128 | RTCC_INTERNAL );
set_timer0 ( 61 );
#INT_RTCC void TIMER_INTERRUPT ( void )
{
set_timer0(61); /* reset the timer */
my_counter = my_counter + 1
}
___________________________
This message was ported from CCS's old forum
Original Post ID: 11838 |
|
|
Barry Gershenfeld Guest
|
Re: Using TIMER0 on 16F84 |
Posted: Tue Feb 18, 2003 3:31 pm |
|
|
:=need some help understanding how TIMER0 is setup
You have the right idea, in fact I think it will work if you add enable_interrupts(GLOBAL) after your initialization.
If you can understand the data sheet, it's a good idea to read how things work. You can gloss over the register names and bit positions (though it's good to become familiar with them). Then when you go back to the CCS manual you will recognize things. "Oh, setup_timer0() must set those same things the data sheet told me to do..."
You should arrange your code and understand as follows:
// This is ok but I think the chip starts with it turned off anyway.
disable_interrupts ( GLOBAL );
// You don't want to enable interrupts, until you have set up the
// hardware that is going to do the interrupts!
setup_timer_0 ( RTCC_DIV_128 | RTCC_INTERNAL );
// It's still not set up completely:
set_timer0 ( 61 );
// Now it's ok to enable the interrupt
enable_interrupts (INT_RTCC);
// But all interrupts require the GLOBAL (called GIE on the chip)
// interrupt--they ALL go through that bit.
enable_interrupts (GLOBAL)
Your interrupt routine looks fine.
Barry
___________________________
This message was ported from CCS's old forum
Original Post ID: 11847 |
|
|
Freddie L Guest
|
Re: Using TIMER0 on 16F84 |
Posted: Tue Feb 18, 2003 6:46 pm |
|
|
<font face="Courier New" size=-1>Thanks for the post.
I was not clear on how to setup the timer to rollover at the desired interval. I think I figured it out by experiment. (PCM Programmer suggested this method in a prior post!)
If using the FOSC Oscillator (the main oscillator running your PIC) for TIMER0 , your Interrupt Service Routine Function will be called every X seconds, where X is calculated as:
X= (4*Prescaler*256)/(FOSCinHz)
So using the following:
1) 10MHz crystal
2) RTCC_DIV_8
X= (4*8*256)/(10000000) = 0.0008192 seconds
The following code works and calls the Interrupt Service Routine every 818us (per my scope). I get a nice pulse each time the Interrupt Service Routine is called. My calculations show that the Interrupt Service Routine Function should be called every 819us.
The PIC16F84 Data Sheet Figure 6.1 talks about a 2 cycle delay to sync the internal clocks after the PSOut stage. Can anyone explain exactly what this is? Does it happen each time the timer rolls over, so there is a 2 instruction delay built into each rollover?
// 84tmrtest.c
// Working Test Program
// TIMER0 INTERRUPT
#include <16f84a.h>
#fuses HS,NOWDT,PUT,NOPROTECT
#use delay(clock=10000000)
#case
// ----- Glogal Variables
int i, my_timer;
void main(void)
{
delay_ms(100); //stabilization time for PIC
disable_interrupts ( GLOBAL );
setup_timer_0 ( RTCC_DIV_8 | RTCC_INTERNAL );
set_timer0 (0);
enable_interrupts ( GLOBAL );
enable_interrupts (INT_RTCC);
while(1)
{
output_low(PIN_B3); //on
delay_ms(100);
output_high(PIN_B3); //off
delay_ms(100);
}
} //end main
#INT_RTCC
TIMER_INTERRUPT ( )
{
//set_timer0(0);
output_low(PIN_B4);
delay_us(5);
output_high(PIN_B4);
}
:=I'm using TIMER0 for the first time and need some help understanding how TIMER0 is setup and the PCM TIMER0 calls. I'm finding the CCS Manual (August 2002) and the example program ex_stwt.c lacking.
:=
:=I need to keep track of time since a certain event occurred. I thought that I could setup TIMER0 to roll over every 2ms and use an Interrupt Routine to increment a counter each time the timer rolls over, this way a 1byte counter variable could keep track of 510ms. (pretty standard from what I've read)
:=
:=I put together the following code from other posts. I'm not sure exactly what the setup_timer_0() and set_timer() commands are doing and how to calculate the correct passed values for 10Mhz clock, 2ms rollover etc... If someone could point me to a tutorial or provide a simple commented snip of code I would greatly appreciate it. (I've read the manuals but I'm still confused. A good example would straighten me out.) Thanks.
:=
:=disable_interrupts ( GLOBAL );
:=enable_interrupts (INT_RTCC);
:=setup_timer_0 ( RTCC_DIV_128 | RTCC_INTERNAL );
:=set_timer0 ( 61 );
:=
:=#INT_RTCC void TIMER_INTERRUPT ( void )
:={
:= set_timer0(61); /* reset the timer */
:=
:= my_counter = my_counter + 1
:=} </font>
___________________________
This message was ported from CCS's old forum
Original Post ID: 11854 |
|
|
Barry Gershenfeld Guest
|
Re: Using TIMER0 on 16F84 |
Posted: Wed Feb 19, 2003 4:04 pm |
|
|
:=The PIC16F84 Data Sheet Figure 6.1 talks about a 2 cycle delay to sync the internal clocks after the PSOut stage. Can anyone explain exactly what this is? Does it happen each time the timer rolls over, so there is a 2 instruction delay built into each rollover?
The one in the figure (5.1, isn't it?) shows a delay between a clock and the actual counting. You wouldn't care about this unless you were using an external clock, and only then if you expected some sort of synchronization. It doesn't affect the rollover.
But there is another 2-cycle delay--when you write to the TMR0 register two more cycles happen before it is loaded in. So when you load TMR0 with 61 you would use 63 (shortening the time before you reach 256)...unless of course you know all this and your 61 is a corrected version of 59.
Barry
___________________________
This message was ported from CCS's old forum
Original Post ID: 11900 |
|
|
|
|
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
|