|
|
View previous topic :: View next topic |
Author |
Message |
Bart
Joined: 12 Jul 2005 Posts: 49
|
Timing problems betwee two interrupts ? |
Posted: Thu Aug 25, 2005 4:45 pm |
|
|
Hello,
As I am still newbie, I can't directly find why my blue led is not flickering at a constant interval.
It blinks about 3 (or 6 or 9 or 10) times correct and than it give a long (not 100 ms but about 1 sec) blink. This repeats.
Is this somewere a confusion between the two interrupt routines ?
Thanks.
PS : some people will recognise parts of the code.
Code: | #include <16F877.h>
#fuses HS, NOWDT, NOPROTECT
#use delay(clock=20000000)
#use rs232(baud=4800, xmit=PIN_B1, rcv=PIN_B0,stream=GPS)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7,stream=MODEM)
#define GPS_BUFFER_SIZE 70
#define MSEC_500 (76) // 20.000.000/(4*128*256) per sec /2
#define MSEC_100 (15)
#define LED_BLUE PIN_A0
#define LED_GREEN PIN_A1
#define LED_RED PIN_A2
static char GPS_buffer[GPS_BUFFER_SIZE];
static char GPS_code[] = "$GPRMC";
static char* GPS_p = GPS_buffer;
static int GPS_state = 0;
static short GPS_done = TRUE;
static short GPS_found = FALSE;
int8 BLINK_RATE, counter, ON_TIME;
int1 system_on;
#INT_RTCC
clock_isr() {
if(system_on)
{
counter++;
if (counter == BLINK_RATE) {output_high(LED_BLUE);}
if (counter == ON_TIME) {output_low(LED_BLUE);
counter = 0;}
}
}
#int_ext
void GPS_isr()
{
char c;
c = fgetc(GPS);
if( GPS_found == FALSE ) { GPS_found = TRUE; }
if( GPS_state < 6 )
{
if( c == GPS_code[GPS_state] )
{
if( GPS_state == 0 ) { GPS_p = GPS_buffer; }
*GPS_p = c;
GPS_p++;
GPS_state++;
}
else { GPS_state = 0; }
}
else
{
if( c == 0x0d ) // carriage return
{
*GPS_p = 0;
GPS_done = TRUE;
disable_interrupts(INT_EXT);
}
else
{
*GPS_p = c;
GPS_p++;
GPS_state++;
}
}
}
main()
{
counter =0;
system_on =1;
BLINK_RATE=MSEC_500 * 2;
ON_TIME=BLINK_RATE + MSEC_100;
// initialise INTERRUPTS
set_rtcc(0);
setup_counters(RTCC_INTERNAL, RTCC_DIV_128);
enable_interrupts(INT_RTCC);
ext_int_edge(H_TO_L);
enable_interrupts(INT_EXT);
enable_interrupts(GLOBAL);
// Version output to MODEM (= PC with Hyperterminal)
fprintf(MODEM," PIC Online\n\r");
fprintf(MODEM," Version : 0.0.4\n\r");
fprintf(MODEM," Copyright 2005 Bart De Pauw\n\r");
fprintf(MODEM,"\n\r");
while(TRUE)
{
if( GPS_found && GPS_done )
{
fputs(GPS_buffer,MODEM); // <= gps string at ones to MODEM.
// split GPS string in separate fields
// to program
// Output obtained fields to MODEM stream.
// fprintf(MODEM,"Date : \n\r");
// fprintf(MODEM,"Time : \n\r");
// fprintf(MODEM,"Speed : \n\r");
// fprintf(MODEM,"Heading : \n\r");
// fprintf(MODEM,"Lat : \n\r");
// fprintf(MODEM,"Lon : \n\r");
// fprintf(MODEM,"Fix : \n\r");
// fprintf(MODEM,"Satelites used : \n\r");
// fprintf(MODEM," : \n\r");
// fprintf(\n\r");
GPS_state = 0;
GPS_done = FALSE;
enable_interrupts(INT_EXT);
}
}
}
// ---------------------------------------------------------
|
_________________ I like Skype (www.skype.com), my username is BplotM |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Fri Aug 26, 2005 9:16 am |
|
|
The routine for blinking the led looks fine to me, so I guess the error is in the other interrupt.
Interrupt routines should be as fast as possible, never implement any blocking function calls in an interrupt routine. Once an interrupt routine is active it will prohibit other interrupts from executing.
In your external interrupt routine you are calling fgetc() which is a potential blocking function, if no data is available it will wait for a character to arrive.
What is connected to your external interrupt line?
Is it possible for you to use the serial receive (INT_RX) instead? |
|
|
Bart
Joined: 12 Jul 2005 Posts: 49
|
|
Posted: Fri Aug 26, 2005 2:41 pm |
|
|
( Bedankt ckielstra voor de reactie ! )
To the external interrupt line there is a serial GPS connected with generate a interrupt when the data string comes in. So, normally, as I detect the start off the string with the interrupt, the fgetc() never has to wait. (String is about 70 characters long).
The only I can thing is that it stays to long in that interupt routine for putting the string in the buffer. As you say, a new interrupt will not start before the previous is finished, I thing I am missing some blinking interupts.
Can someone confirm this ? Is there a solution ?
Thanks. _________________ I like Skype (www.skype.com), my username is BplotM |
|
|
Ttelmah Guest
|
|
Posted: Fri Aug 26, 2005 3:04 pm |
|
|
One thing that would make things go really screwy, would be if there is an edge seen on the interrupt, and this is not the leading edge of a byte (noise, or a repeated trigger from the tail of the last byte received). In this case, the system will hang at the fgetc. Though it involves a couple of extra instructions, I'd add a test that the signal line is low, before calling fgetc, and return if not. It might fix the problem.
One problem, might be the case that the system is in the timer interrupt, when the external interrupt occurs. The typical interrupt 'latency' is about 25 instructions. so if a timer interrupt occured just at the same moment as a external interrupt, given that it has priority (this is implicit in the handler being first), then you will have the 25 instructions into the routine, the routine itself (perhaps another 20 instructions), plus the return time (about 20 instructions), plus about 28 instructions to get into the external interrupt code. This gives a worst case of about 93 instructions from the moment the interrupt occurs, to actually arriving at the fgetc routine. This then checks the signal for being low. This should be true (about 20uSec after the edge), but the time involved might make it unreliable. You can reduce this time, by giving the external interrupt priority over the LED code. Either move it's routine in front of the RTCC code, or use the 'priority' statement to define this as the higher priority routine. though it seems 'odd' to raise the priority of the interrupt that is not giving the problem, it might help.
So, I'd try testing for the start bit, and reversing the interrupt priority.
Best Wishes |
|
|
|
|
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
|