|
|
View previous topic :: View next topic |
Author |
Message |
Sebastian
Joined: 01 Dec 2003 Posts: 21 Location: Milan Italy
|
RS232 INTERRUPT PROBLEM |
Posted: Wed Jan 04, 2006 8:34 am |
|
|
HI ALL !!
I HAVE TRY TO MANAGE INTERRUPTS.
I MUST TURN ON RXLED ( IN MY CODE ) AFTER EVERY RX 232 INTERRUPT BUT IN THIS WAY I SEE LED ON ONLY AFTER THE SECOND
PUSH BUTTON .
SOMEONE CAN TELL ME A RIGHT WAY........
#if defined(__PCH__)
#include <18F452.h>
#include <string.H>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=20000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7,ERRORS)
#endif
#include <input.c>
#define STX 0x02 // Start of Transmition
#define ETX 0x03 // End of Transmition
#define AD 0x55
#define SEMICOLON 0x3B
#define LED1 PIN_B0
#define LED2 PIN_B1
#define LED3 PIN_B2
#define LED4 PIN_B3
#define LED5 PIN_B4
#define LED6 PIN_B5
#define RFLED PIN_A1
#define RXLED PIN_A2
#define PUSH_BUTTON PIN_D0
//------------------------------------------------------------------------------
#define BUFFER_SIZE 9
//------------------------------------------------------------------------------
#DEFINE BUFFER_COMPARE
//------------------------------------------------------------------------------
// GLOBALS
static int8 char_rcved, data_valid, next_in;
static int8 buffer_overflow, stream_complete;
static int8 sermssg[BUFFER_SIZE];
/////////////////////////////////////////////////////////////////////
static int8 stringa[10]= {STX,0,0,0,1,1,SEMICOLON,AD,ETX};
// a string always ends with a NULL, so 9 char + NULL = [10]
////////////////////////////////////////////////////////////////////////
set_tris_b(0x00);
set_tris_d(0b11111111);
set_tris_a(0b00000000);
//------------------------------------------------------------------------------
#INT_RDA
void isr_serial_rcv()
{
char_rcved = getc(); // Get the incoming char
if ( char_rcved == STX )
{ next_in = 0; // Init the index
data_valid = TRUE; // Enable buffering
buffer_overflow = FALSE;
}
if ( data_valid )
{ sermssg[next_in] = char_rcved;
next_in++;
if ( next_in > BUFFER_SIZE ) // String longer than expected
{ data_valid = FALSE; // Stop buffering
buffer_overflow = TRUE;
}
if ( char_rcved == ETX )
{ data_valid = FALSE; // Stop buffering
stream_complete = TRUE;
}
}
}
void main()
{
delay_ms(400);
//set_tris_b(0x00);
//set_tris_d(0b11111111);
//set_tris_a(0b00000000);
stream_complete = FALSE;
enable_interrupts(GLOBAL);
while(1)
{
enable_interrupts( INT_RDA );
do{ // While stream_complete
do{
output_high(LED6);
delay_ms(200);
output_low(LED6);
delay_ms(200);
}while(input(PUSH_BUTTON));
(!input(PUSH_BUTTON));
output_b(0x00);
output_low(RXLED);
delay_ms(2000);
printf("\x2");
printf("0001wdloa;1;");
printf("\xFF");
printf("\x3");
//RX STX,0,0,0,1,1,SEMICOLON,AD,ETX RXLED ON
output_high(LED1);
delay_ms(2000);
////////////////////////////////// INTERRUPT
}while ( !stream_complete );
do{ // While stream_complete
do{
output_high(LED5);
delay_ms(200);
output_low(LED5);
delay_ms(200);
}while(input(PUSH_BUTTON));
(!input(PUSH_BUTTON));
output_b(0x00);
output_low(RXLED);
delay_ms(2000);
printf("\x2");
printf("0001wdloa;2;");
printf("\x80");
printf("\x3");
//RX STX,0,0,0,1,1,SEMICOLON,AD,ETX RXLED ON
output_high(LED2);
delay_ms(2000);
//////////////////////////////////INTERRUPT
}while ( !stream_complete );
if ( stream_complete )
{
stream_complete = FALSE; // IMPORTANT: If not the program re-enter
if ( !buffer_overflow )
{
disable_interrupts( INT_RDA );
#IFDEF BUFFER_COMPARE //////////////////////////////////////////////////////////
if (strcmp(stringa,sermssg))
{
output_high(RXLED);
}
#ENDIF //////////////////////////////////////////////////////////////////////////
} // if ( !buffer_overflow )
if ( buffer_overflow )
{// something wrong related to incoming string
output_b(0xff);
delay_ms(100); // Just to see a change in output_b
buffer_overflow = FALSE; // clear the fault !!!!
}
} // if ( stream_complete )
} // while(1)
} // void main() |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Wed Jan 04, 2006 10:07 am |
|
|
First two remarks:
1) TYPING YOUR MESSAGE IN CAPITAL LETTERS IS CONSIDERED NOT POLITE.
2) Please use the 'code' button when posting code so the indenting of your code is kept intact.
I haven't checked all your code because the flow is hard to follow but I found two errors: Code: | #define BUFFER_SIZE 9
.
.
.
if ( data_valid )
{
sermssg[next_in] = char_rcved;
next_in++;
if ( next_in > BUFFER_SIZE ) // String longer than expected
{
data_valid = FALSE; // Stop buffering
buffer_overflow = TRUE;
}
if ( char_rcved == ETX )
{ data_valid = FALSE; // Stop buffering
stream_complete = TRUE;
}
}
|
- On reception of a message with length 10 or larger you will first overwrite data in memory at location sermssg[9] before detecting the message to be too long.
- In case of errors you will stop receiving and never set the stream_complete flag to TRUE. In your main() you are testing this flag in a while loop and your program loops forever...
Code: | delay_ms(2000);
////////////////////////////////// INTERRUPT | This is terrible code! You have a nice interrupt routine receiving data in the background and then you are blocking your program for 2 seconds while waiting for a response???
Much nicer is a construction like this: Code: | timeout=0;
do
{
delay_ms(10);
timeout++;
} while ((!stream_complete) && (timeout < 200)); |
|
|
|
Sebastian
Joined: 01 Dec 2003 Posts: 21 Location: Milan Italy
|
little help |
Posted: Thu Jan 05, 2006 6:46 am |
|
|
Hi ckielstra.
I'm new in PIC programming ......can i ask you one advice ?
In my code I transmit two stream ,stream1 and stream2 after push_button.After every push_button ,(stream1 is a command),
I recive always the same nine caracters {STX,0,0,0,1,1,SEMICOLON,AD,ETX}; that sign the correct recive command from a board.
For to know if the command is arrived and processed I want turn on
RXLED .
What i must to do for this .
The interrupt routine see only the second return string not the first.
I can delete the input string and remove buffer overflow.
Have you any suggestions.
How can write compare and delete the string input message every time.
Thank you in advance
Code: | #if defined(__PCH__)
#include <18F452.h>
#include <string.H>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=20000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7,ERRORS)
#endif
#include <input.c>
#define STX 0x02 // Start of Transmition
#define ETX 0x03 // End of Transmition
#define AD 0x55
#define SEMICOLON 0x3B
#define LED1 PIN_B0
#define LED2 PIN_B1
#define LED3 PIN_B2
#define LED4 PIN_B3
#define LED5 PIN_B4
#define LED6 PIN_B5
#define RFLED PIN_A1
#define RXLED PIN_A2
#define PUSH_BUTTON PIN_D0
//------------------------------------------------------------------------------
#define BUFFER_SIZE 9
//------------------------------------------------------------------------------
#DEFINE BUFFER_COMPARE
//------------------------------------------------------------------------------
// GLOBALS
static int8 char_rcved, data_valid, next_in;
static int8 buffer_overflow, stream_complete;
static int8 sermssg[BUFFER_SIZE];
/////////////////////////////////////////////////////////////////////
static int8 stringa[10]= {STX,0,0,0,1,1,SEMICOLON,AD,ETX};
// a string always ends with a NULL, so 9 char + NULL = [10]
////////////////////////////////////////////////////////////////////////
set_tris_b(0x00);
set_tris_d(0b11111111);
set_tris_a(0b00000000);
//------------------------------------------------------------------------------
#INT_RDA
void isr_serial_rcv()
{
char_rcved = getc(); // Get the incoming char
if ( char_rcved == STX )
{ next_in = 0; // Init the index
data_valid = TRUE; // Enable buffering
buffer_overflow = FALSE;
}
if ( data_valid )
{ sermssg[next_in] = char_rcved;
next_in++;
if ( next_in > BUFFER_SIZE ) // String longer than expected
{ data_valid = FALSE; // Stop buffering
buffer_overflow = TRUE;
}
if ( char_rcved == ETX )
{ data_valid = FALSE; // Stop buffering
stream_complete = TRUE;
}
}
}
void main()
{
delay_ms(400);
stream_complete = FALSE;
enable_interrupts(GLOBAL);
while(1)
{
enable_interrupts( INT_RDA );
do{ // While stream_complete
do{
output_high(LED6);
delay_ms(200);
output_low(LED6);
delay_ms(200);
}while(input(PUSH_BUTTON));
(!input(PUSH_BUTTON));
output_b(0x00);
output_low(RXLED);
delay_ms(2000);
//STREAM 1
printf("\x2");
printf("0001wdloa;1;");
printf("\xFF");
printf("\x3");
//RX STX,0,0,0,1,1,SEMICOLON,AD,ETX RXLED ON
output_high(LED1);
////////////////////////////////// INTERRUPT
}while ( !stream_complete );
do{ // While stream_complete
do{
output_high(LED5);
delay_ms(200);
output_low(LED5);
delay_ms(200);
}while(input(PUSH_BUTTON));
(!input(PUSH_BUTTON));
output_b(0x00);
output_low(RXLED);
delay_ms(2000);
//STREAM 2
printf("\x2");
printf("0001wdloa;2;");
printf("\x80");
printf("\x3");
//RX STX,0,0,0,1,1,SEMICOLON,AD,ETX RXLED ON
output_high(LED2);
//////////////////////////////////INTERRUPT
}while ( !stream_complete );
if ( stream_complete )
{
stream_complete = FALSE; // IMPORTANT: If not the program re-enter
if ( !buffer_overflow )
{
disable_interrupts( INT_RDA );
#IFDEF BUFFER_COMPARE //////////////////////////////////////////////////////////
if (strcmp(stringa,sermssg))
{
output_high(RXLED);
}
#ENDIF //////////////////////////////////////////////////////////////////////////
} // if ( !buffer_overflow )
if ( buffer_overflow )
{// something wrong related to incoming string
output_b(0xff);
delay_ms(100); // Just to see a change in output_b
buffer_overflow = FALSE; // clear the fault !!!!
}
} // if ( stream_complete )
} // while(1)
} // void main() |
|
|
|
litoman
Joined: 04 Nov 2005 Posts: 3
|
INT_RDA problem |
Posted: Thu Jan 05, 2006 7:50 am |
|
|
Yes i think that there is a bug with INT_RDA in PIC 18F452 and 18F252 etc.
When the PIC go into interruption routine it never go out or it reset.
I have a same problem. |
|
|
litoman
Joined: 04 Nov 2005 Posts: 3
|
|
|
Ttelmah Guest
|
|
Posted: Thu Jan 05, 2006 8:23 am |
|
|
The original poster, is not using high priority interrupts, so the reference thread doesn't apply.
There is nothing wrong with INT_RDA, on the 452/252, I have sometyhing in excess of a couple of thousand units out in the field, using these chips, and interrupt driven I/O, without problems.
Now the code unfortunately, is almost illegible in places, because of the layout. However some bits leap out as potential problems. If the counter, gets to '9', it will not flag a buffer overflow (because the test, tests for the counter being greater than the buffer size), yet the byte received will go to sermssg[9], which will overwrite the buffer area,and may cause disaster.
What is this meant to do?
Code: |
}while(input(PUSH_BUTTON));
(!input(PUSH_BUTTON));
|
The first line, is the termination statement for an earlier 'do', but the second line seems to have been left over from somewhere...
Tidy the code. Fix the buffer size fault, and if it still doesn't work, repost it (using the code button), and somebody may be then able to see what is wrong.
Best Wishes |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Thu Jan 05, 2006 4:46 pm |
|
|
The main problem in the program is that after sending a stream over RS232 there is no time allowed for the response to arrive.
Current implementation
Code: | do
{
wait for button
2 sec delay <-- makes no sense here.
send Stream1
} while (no response received) | Very likely the 2 second delay was supposed to be located after sending Stream1.
A better implementation would be
Code: | wait for button
send Stream1
while (no response received)
{
// Do nothing (or blink a led)
} |
|
|
|
jack Guest
|
|
Posted: Thu Jan 05, 2006 11:15 pm |
|
|
Hi, I have a question about....RS232 and Timer0 interrupt...
I'm sending data over rs232 at 2400baud...at the same time timer0 overflow interrupt @ 64.5msec occurs through out, will the data be recieved safely??
Thanks |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Fri Jan 06, 2006 3:07 am |
|
|
jack wrote: | Hi, I have a question about....RS232 and Timer0 interrupt...
I'm sending data over rs232 at 2400baud...at the same time timer0 overflow interrupt @ 64.5msec occurs through out, will the data be recieved safely??
Thanks | Please post new questions in a new thread. |
|
|
|
|
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
|