View Single Post
  #7   Spotlight this post!  
Unread 06-02-2006, 12:11
tribotec_ca88's Avatar
tribotec_ca88 tribotec_ca88 is offline
FIRST-a-holic
AKA: Camila Fitzgibbon
FRC #1382 (Tribotec Team)
Team Role: Student
 
Join Date: Jan 2004
Rookie Year: 2004
Location: São José dos Campos, Brazil
Posts: 194
tribotec_ca88 is just really nicetribotec_ca88 is just really nicetribotec_ca88 is just really nicetribotec_ca88 is just really nicetribotec_ca88 is just really nice
Send a message via ICQ to tribotec_ca88 Send a message via MSN to tribotec_ca88 Send a message via Yahoo to tribotec_ca88
Re: How to use a "Timer"

Quote:
Originally Posted by MacFlightSierra
one loop of the controller is 26.2 millis - approx 38 loops per second. just add a variable to count till 38 and then reset it to zero

good luck/behatzla'ha
Hmm...i wouldn't recommend using the "approx 38 loops per second" method.

If you're looking for greater precision i recommend using the interrupt-driven timers. Our team is currently using Timer1 of the five PIC timers. Perhaps i'm not the best person to explain you exactly how they work but let me see if i can help...

First off, we created a function known as Init_timers(); (inside a .c file of our choice), which is called from inside User_Initialization() under user_routines.c.

Inside Init_timers we wrote the following code (to initialize and configure Timer1):

void Init_timers(void)
{

T1CONbits.T1CKPS0 = 1; // 1:8 Prescale (clock=1.25MHz/each tick=800ns)
T1CONbits.T1CKPS1 = 1;

TMR1H = 0x85; // sets Timer1's most significant byte
TMRIL = 0xED; // sets Timer1's least significant byte


T1CONbits.TMR1CS = 0; // Uses Internal clock

T1CONbits.T1OSCEN = 0; // Internal oscillator off

T1CONbits.RD16 = 1; // Timer1 operations done in 16-bit accesses


IPR1bits.TMR1IP = 0; // Sets interrupt as low priority

PIR1bits.TMR1IF = 0; // Overflow flag

PIE1bits.TMR1IE = 1; // Timer1 interrupt OK

INTCONbits.GIEL = 1; // Low priority interrupts OK

T1CONbits.TMR1ON = 1; // Timer1 set as on

}

Next you'll need to add a few things inside InterruptHandlerLow() inside user_routines_fast. This is a system function; I.E. when an interrupt is set, this function is immediately called by IFI's interrupt handler. You do not need to call it from anywhere in your code, however, you will need to include the following lines of code inside it. You'll notice this function already has several "IF" loops so all you have to do is add one more...

void InterruptHandlerLow ()
{

if[...]

else if (PIR1bits.TMR1IF && PIE1bits.TMR1IE) // checks to see if overflow has occured
{
PIR1bits.TMR1IF = 0; // resets Timer1 overflow
TMR1L = 0xED;
TMR1H = 0x85;
timer1_count++; // Timer1 counter incremented every 25ms
}


[...]

} // end of InterruptHandlerLow() function

Since I'm assuming you'll be working with timers inside your Autonomous code (as are we), all you'd have to do next is use "IF"s to compare the timer1_count variable. As was explained, the timer increments every 25ms, so if for example you wanted to have your robot execute a specific part of your code for 1s (=1000 ms), simple!: check if timer1_count is equivalent to 40...! For 2 seconds, 80, for 10 seconds, 400, etc etc etc...

This may not perhaps be the most accurate method but from our experiences it suited our specific needs...

Hope this helps...
any questions whatsoever, pm me...



__________________
1382 Tribotec Team - Brazil
-----------------------------------------------
2005 NJ Regional GM Industrial Design Award
2005 NJ Regional Website Excellence Award
2004 NJ Regional Semifinalists
-----------------------------------------------