CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

RS-232 data between PC and PIC getting jumbled

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Rob
Guest







RS-232 data between PC and PIC getting jumbled
PostPosted: Sat Apr 24, 2004 1:27 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Sat Apr 24, 2004 5:37 pm     Reply with quote

Hi Rob,

Pls post your code, itīs the way we can help you.

Thks,

Humberto
Rob
Guest







PostPosted: Sat Apr 24, 2004 5:43 pm     Reply with quote

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







PostPosted: Sat Apr 24, 2004 5:46 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Sat Apr 24, 2004 6:16 pm     Reply with quote

Hi Rob,

I posted an example in a past thread that I think it's applicable in this case: Divide your tasks
1)Receive and store using a reliable way
2)Retrieve and analize the buffered string.
3)Make your stuff accordingly

http://www.ccsinfo.com/forum/viewtopic.php?t=18974&highlight=buffer+rs232

Hope this help,

Humberto
Humberto



Joined: 08 Sep 2003
Posts: 1215
Location: Buenos Aires, La Reina del Plata

View user's profile Send private message

PostPosted: Sun Apr 25, 2004 6:11 am     Reply with quote

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







PostPosted: Sun Apr 25, 2004 3:02 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Mon Apr 26, 2004 8:42 am     Reply with quote

Hola Rob,

Code:


void main()
{
   for(c=0;c<11;c++)   
      {
         sermssg[c] = getc();
      }
   .....................
   .....................
}
   


is a disaster invitation...

Humberto
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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