View previous topic :: View next topic |
Author |
Message |
Rob Guest
|
RS-232 data between PC and PIC getting jumbled |
Posted: Sat Apr 24, 2004 1:27 pm |
|
|
Hello,
I am using a 16F87 to communicate with a PC using the MAX232 level converter. I am running the PIC at 8MHz using the internal oscilattor. The baud rate is 9600. The problem I have is kind of strange. The PC sends the PIC an array of 11 bytes, 1 at a time (I am currently using a terminal to simulate my C# program). Upon reception, the PIC echos the array back. The PIC is getting all of the data, but it is sometimes shifted in the array a acouple of times. This problem is somewhat intermitant. I have run into this before on a rabbit board because of its circular buffers, but switching to getc() instead of gets() and keeping a close eye on the buffers usually solves that one. I am not implementing anything that sophisticated on the PIC though, just using a for loop to collect the 11 bytes using getc() and then using another to echo them back with putc(). Is this just the terminal program on the PC or is it something in the PIC? Could it be something electrical, like in the MAX232 circuitry. I read through maxim's documentation and could find nothing about placement or anything of that nature, however the max232 does contain charge pumps. Does the proximity of the PIC to the MAX232 affect data integrity? My data is not last, it just arrives in the worng order. Any clues at all? I'm stumpted.
Thanks,
Rob |
|
|
Humberto
Joined: 08 Sep 2003 Posts: 1215 Location: Buenos Aires, La Reina del Plata
|
|
Posted: Sat Apr 24, 2004 5:37 pm |
|
|
Hi Rob,
Pls post your code, itīs the way we can help you.
Thks,
Humberto |
|
|
Rob Guest
|
|
Posted: Sat Apr 24, 2004 5:43 pm |
|
|
Sorry, I forgot to include my code.
Code: |
for(c=0;c<11;c++)
{
old[c] = sermssg[c];
sermssg[c] = getc();
if(c>1)
LEDdisplay(c-2,old[c]);
}
sermssg[1] = 0;
if((sermssg[0]!=4))//if mssg not intended for LED's
sermssg[1]=3;
for(c=2;c<11;c++)
{
LEDdisplay(c-2,old[c]);
if(sermssg[c]>10)//if data is out of range
sermssg[1]=3;
} |
|
|
|
Rob Guest
|
|
Posted: Sat Apr 24, 2004 5:46 pm |
|
|
I messed up the last submission, here's what you wanted to see.
Code: |
device PIC16F87
#fuses HS,NOWDT,INTRC_IO,NOPROTECT,NOLVP
#include <stdio.h>
#use STANDARD_IO(A)
#use STANDARD_IO(B)
#use delay(clock=8000000)
#define PIN_A0 40
#define PIN_A1 41
#define PIN_A2 42
#define PIN_A3 43
#define PIN_A4 44
#define PIN_A5 45
#define PIN_A6 46
#define PIN_A7 47
#define PIN_B0 48
#define PIN_B1 49
#define PIN_B2 50
#define PIN_B3 51
#define PIN_B4 52
#define PIN_B5 53
#define PIN_B6 54
#define PIN_B7 55
#use rs232(baud=9600, xmit=PIN_B5, RCV=PIN_B2, PARITY=N)
char sermssg[11];// Global
void main()
{
for(c=0;c<11;c++)
{
sermssg[c] = getc();
}
sermssg[1] = 0;
if((sermssg[0]!=4))//if mssg not intended for LED's
sermssg[1]=3;
for(c=2;c<11;c++)
{
if(sermssg[c]>10)//if data is out of range
sermssg[1]=3;
}
for(c=0;c<11;c++)
{
putc(sermssg[c]);
}
//there is more here but it is irrelevant to the serial problem.
} |
|
|
|
Humberto
Joined: 08 Sep 2003 Posts: 1215 Location: Buenos Aires, La Reina del Plata
|
|
|
Humberto
Joined: 08 Sep 2003 Posts: 1215 Location: Buenos Aires, La Reina del Plata
|
|
Posted: Sun Apr 25, 2004 6:11 am |
|
|
Data packet example:
STX D0 D1 D2 D3 D4 D5 D6 D7 D8 D9 DA ETX
STX: HEAD char
ETX: TAIL char
Code: |
#define BUFFER_SIZE 12
// GLOBALS
static int8 char rcved, data_valid, next_in;
static int8 buffer_overflow, stream_complete;
static int8 sermssg[BUFFER_SIZE];
#INT_RDA
void isr_serial_rcv()
{
char_rcved = getc(); // Get the incoming char
if ( char_rcved == STX ) // Catch the HEAD char
{ next_in = 0; // Init the index
data_valid = TRUE; // Enable buffering
buffer_overflow = FALSE; // For further use
}
if ( data_valid ) // If enable to store...
{ sermssg[next_in] = char_rcved; // Store it in buffer at address [next_in]
next_in++; // Increment index
if ( char_rcved == ETX ) // Catch the TAIL char
{ data_valid = FALSE; // Stop buffering
}
if ( next_in > BUFFER_SIZE ) // String longer than expected
{ data_valid = FALSE; // Stop buffering
buffer_overflow = TRUE;
}
if ( !data_valid )
{ stream_complete = TRUE;
}
}
}
void main()
{
stream_complete = FALSE;
enable_interrupts(INT_RDA);
enable_interrupts(GLOBAL);
while(1)
{
do
{
// Do all other stuff....
}while ( !stream_complete );
if ( stream_complete )
{
if ( !buffer_overflow )
{
disable_interrupts( INT_RDA );
// Analize the received string...
your code...
if(( sermssg[1]!=4 )) // if mssg not intended for LED's
sermssg[2]=3;
....................
....................
etc...
enable_interrupts( INT_RDA );
}
if ( buffer_overflow )
{
// something wrong related to incoming string
}
}
}
}
|
Hope this clarify previous post..
Humberto |
|
|
Rob Guest
|
|
Posted: Sun Apr 25, 2004 3:02 pm |
|
|
That's an excellent idea! Thanks for the help. But just out of curiosity do you know why this happens?
-Rob |
|
|
Humberto
Joined: 08 Sep 2003 Posts: 1215 Location: Buenos Aires, La Reina del Plata
|
|
Posted: Mon Apr 26, 2004 8:42 am |
|
|
Hola Rob,
Code: |
void main()
{
for(c=0;c<11;c++)
{
sermssg[c] = getc();
}
.....................
.....................
}
|
is a disaster invitation...
Humberto |
|
|
|