|
|
|
![]() |
|
|||||||
|
||||||||
![]() |
| Thread Tools | Rate Thread | Display Modes |
|
#1
|
||||
|
||||
|
Hullo everyone. I'm Evan Wilson, lead programmer for Team 2172, St. Edward High School.
Our robot is all crated and shipped off... with horrible loop-counting timekeeping. In the past, I've heard of creating a real time clock with the Timer1 module in the PIC controller. Is it humanly possible to create such a program? I DO know some PIC assembly, and certainly C. I assume this would be intensively assembly. Also, is there actually a crystal in the controller already? When reading the datasheet for the chip, it almost made it sound as if I'd need to do some whacked out solder job... I would like to have gotten this done for this year's competition, but seeing as we have no adult mentors (and I'm a junior with a bit of a tight schedule) we couldn't cram in the work for that. Anyways, thanks to anyone who could help, give links, etc. |
|
#2
|
||||
|
||||
|
Re: Real time clocks, out of the question?
Hi, We too have had te same problem, in easyC there are a total of 6 timers, however, we haven't been able to get any of them to work, i believe timer 1 is used for the camera, but we cant seem to get any of the other timers to work. If any other teams have been able to get them to work, it would be extremely helpfull.
Thanks Malhon |
|
#3
|
||||
|
||||
|
Well, in my case, I've used MPLAB the whole way. But does easyC actually have timers? I dug into the datasheet and found the Timer0 and Timer1 modules in the microcontroller and wasn't sure how to use them.
http://users.tkk.fi/~jalapaav/Electr...ock/index.html That seems a little helpful. |
|
#4
|
||||
|
||||
|
Re: Real time clocks, out of the question?
Yes, EasyC does have timers, six of them. I believe we have used up to three at once, and they all work fine.
What exactly isn't working for your? Could you post your code? Thanks, Nathan |
|
#5
|
||||
|
||||
|
Well, the problem is that I don't have any. Without EasyC, I just have the arm calculating based on loop counting. Multiples of 26.2 ms. There's no way I can switch to EasyC this year. I guess that would be a logical solution for next year.
Is there anyone here who has ever written a timer and interrupt routine for a real time clock? That's really the only thing I could worry about anyways. Otherwise I'll just have to stick with loop counting. |
|
#6
|
|||||
|
|||||
|
Re: Real time clocks, out of the question?
Timers are simple to use, no soldering required.
IFI has a white paper on coding timers that goes into the bits and bytes of it all: http://www.ifirobotics.com/docs/time...004-jan-14.pdf For a description of the timer library calls see the MPLAB-C18-Libraries.pdf manual under C:\mcc18\doc. Here's a sample using the timer libraries: Code:
// In user_routines.c
#include <timers.h>
#define CLOCKOFFSET 60535 //Set timer for 4ms
// Maximum for 16-bit timer 65535 - 5000 (4ms) = 60535
/* Use Timer3 (16-bits) to control our clock */
/* timer set to 4 ms */
// Call from User_Initialization()
OpenTimer3(TIMER_INT_ON &
T3_16BIT_RW &
T3_SOURCE_INT &
T3_PS_1_8
);
WriteTimer3(CLOCKOFFSET); /* Preload timer to overflow after 4ms */
Code:
// In user_routines_fast.c
#include <timers.h>
// globals declared as extern wherever else they are used
volatile unsigned long Clockms=0; // 1 millisecond clock
volatile unsigned int Clockds=0; // 1/10 second
volatile unsigned int Clocksec=0; // 1 second clock
//etc.
// In InterruptHandlerLow()
if (PIR2bits.TMR3IF) /* TIMER 3 INTERRUPT */
{
/** This provides us with a clock for timing events **/
PIR2bits.TMR3IF = 0; /* Clear Timer interrupt flag */
WriteTimer3(CLOCKOFFSET); /* Reset Timer to overflow in 4ms */
Clockms += 4; /* milliseconds */
Clockds = Clockms / 100;
Clocksec = Clockms / 1000;
// etc.
}
Last edited by Mark McLeod : 24-02-2007 at 12:17. |
|
#7
|
||||
|
||||
|
Thank you very much. I hope my assembly serves me well.
I think I can dig up the differences in the new controller. Want to be a mentor... just kidding. |
|
#8
|
||||
|
||||
|
Re: Real time clocks, out of the question?
I wrote some real-time clock code for the EDU-RC a few years ago. Here's a link: http://kevin.org/frc/2005/edu_clock2.zip.
-Kevin |
|
#9
|
||||
|
||||
|
Re: Real time clocks, out of the question?
Okay. Thanks very much Kevin and Mark. The last thing I need to make sure of is the value for the system clock. In the edu_clock code, it's specified as 10MHz. Does anyone know if there would be a difference in the PIC18F8722? I seem to remember reading something about 32.blablabla MHz somewhere. Or maybe it's changeable...
After this, I deserve to be put back into grade school if I can't do the math. THANKS |
|
#10
|
|||||
|
|||||
|
Re: Real time clocks, out of the question?
It's the same 10MHz for the PIC18F8722 we use.
|
|
#11
|
||||
|
||||
|
Quote:
|
|
#12
|
||||
|
||||
|
Re: Real time clocks, out of the question?
There's a nice set of interface functions for using Timer1 here: http://www.chiefdelphi.com/forums/sh...ht=wallclock.c
|
|
#13
|
||||
|
||||
|
Re: Real time clocks, out of the question?
The way Kevin's code sets up the interrupt is the best. The other example code posted/referenced all appear to reload the Timer register each time the interrupt is serviced, and the interrupt service latency then becomes an additive value to the timer's period. To some extent, only reloading the upper byte will help avoid the problem, but its easy to avoid the problem all together by just configuring the timer differently. An added bonus is that a few instruction cycles are removed from the ISR by not having to reload the register each time.
Another thing to remember here is that this microcontroller does not have a divide instruction, so including divide operations in an interrupt routine is forcing the microcontroller to execute a lot of instructions on a frequent basis. Some of the examples provided utilize variables wider than 8 bits, but I didn't notice any cautionary notes for routines that access these variables outside of the interrupt service routine. Because this micrcontroller operates on 8 bits at a time, if a routine were testing a 16 or 32 bit variable and an interrupt occurred in the middle of such a test, the ISR will end up invalidating the foreground operation that it interrupted. No amount of 'volatile' declarations will fix that problem. If the timer value absolutely MUST be greater than 8 bits, then the foreground operations that access this variable must temporarily disable the relevant timer interrupt prior to accessing or manipulating the variable, then re-enable the interrupt after the operation is complete. I tend to use timers that count down to zero because most microcontrollers are able to test for a zero condition in a single instruction, whereas testing for a specific value tends to use two or more instructions... and this is something which is true for the PIC18. In other words: Code:
if (a) {
do_something();
}
Code:
if (a>59) {
do_something();
}
As such I tend to write timer ISR's this way: Code:
// 1ms timer tick ISR
if (Timer1ms) {
--Timer1ms;
}
if (!(--Timer10)) {
Timer10 = 10;
if (Timer10ms) {
--Timer10ms;
}
if (!(Timer100)) {
Timer100 = 10;
if (Timer100ms) {
--Timer100ms;
}
if (!(Timer1000)) {
Timer1000 = 10;
if (Timer1s) {
--Timer1s;
}
}// !Timer1000
} // !Timer100
} // !Timer10
}
Code:
Timer10ms = 100; // Start Timer, 100 * 10ms = 1 second
// elsewhere
if (!(Timer10ms)) { // if timer expired
do_something();
}
Code:
if (Timer) { // if timer is running
if (!(--Timer)) { // decrement, and if it hits zero
Event_Flag = 1; // set event flag
}
}
Code:
Event_Flag = 0; // make sure event flag is cleared
Timer = 100; // start timer
// elsewhere
if (Event_Flag) {
do_something();
}
|
|
#14
|
|||||
|
|||||
|
Re: Real time clocks, out of the question?
I wrote some code that starts uses the timer mentioned above that turns on an LED 1:30 seconds into the operator controller part.
Our team has a "Heads up display" we used last year for shooting, we remade it this year but this was the only use we could come up with. |
|
#15
|
||||
|
||||
|
Alright. I have another question about how the timer variables work in all of these. I've used storage classes/qualifiers occasionally but I don't understand the significance of using, say, extern and volatile to store the timer variables. Could anyone shed some light on this?
|
![]() |
| Thread Tools | |
| Display Modes | Rate This Thread |
|
|
Similar Threads
|
||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| Networkable real-time game simulation for 'Aim High'! test it out now | Bongle | General Forum | 11 | 19-03-2006 23:10 |
| Real time photos from the buckeye regional | Greg Needel | Regional Competitions | 4 | 25-03-2004 12:46 |
| Robot motion after the time has run out. | Randy Ai | Rules/Strategy | 1 | 06-01-2003 17:17 |
| Real Time Scoring | archiver | 2000 | 2 | 24-06-2002 00:09 |
| real time chat | SharkBite | CD Forum Support | 4 | 07-02-2002 21:22 |