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 support@ccsinfo.com

Serial Reception on the PIC16F877

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



Joined: 03 Mar 2004
Posts: 2

View user's profile Send private message Send e-mail MSN Messenger

Serial Reception on the PIC16F877
PostPosted: Wed Mar 03, 2004 7:09 pm     Reply with quote

hello everyone,
i am trying to do serial communication between a pic 16f877 and the PC. I am using the RDA interrupt but i am getting problems receiving the data. I can receive either a single character or a floating point number but i must be able to distinguish between them and determine which character was received. the reception of the single character works but the floating point reception is giving trouble.
i cannot see what is the problem with the code. if anyone can help please do.
thanks in advance.


Code:

#define BUFFER_SIZE 9
char rx_data[BUFFER_SIZE];
char rx_data_L1[BUFFER_SIZE];
char rx_data_L2[BUFFER_SIZE];

int i = 0;
int count = 0;
int rx = 0;
int index = 0;
char mode;
const char Initialize = 'I';
const char Remote = 'R';
const char Stop = 'S';
const char Request = 'Q';
const char Ang_Arm_1 = '$';
const char Ang_Arm_2 = '@';
char rx_char = ' ';

#INT_RDA
serial_int()
{
      if (count == 0)
   {
      rx_data_L1[0] = '$';
      rx_data_L2[0] = '@';

      for(i = 1; i < BUFFER_SIZE - 1; i++)
      {
         rx_data_L1[i] = '0';
         rx_data_L2[i] = '0';
      }
      rx_data_L1[BUFFER_SIZE - 1] = '\0';
      rx_data_L2[BUFFER_SIZE - 1] = '\0';
   }

   rx_data[index] = RCREG;

   if ((rx_data[0] == Ang_Arm_1) || (rx_data[0] == Ang_Arm_2))
      index = 1;
   else
      index = 0;

   if (rx_data[0] == Initialize)
   {
      mode = Initialize;
      count = 0;
      return;
   }
   
   if (rx_data[0] == Remote)
   {
      mode = Remote;
      count = 0;
      return;
   }
   
   if (rx_data[0] == Stop)
   {
      mode = Stop;
      count = 0;
      return;
   }
   
   if (rx_data[0] == Request)
   {
      mode = Request;
      count = 0;
      return;
   }
   
   if (rx_data[0] == Ang_Arm_1)
   {
      mode = Ang_Arm_1;
      rx_data_L1[count] = rx_data[index];
      count++;
      rx_data_L1[count]='\0';

      if (count == BUFFER_SIZE-2)
      {
         rx_data_L1[BUFFER_SIZE-1]='\0';
         count = 0;
         return;
      }
   }
   if (rx_data[0] == Ang_Arm_2)
   {
         mode = Ang_Arm_2;
         rx_data_L1[count] = rx_data[index];
         count++;
         rx_data_L1[count]='\0';

      if (count == BUFFER_SIZE-2)
      {
         rx_data_L2[BUFFER_SIZE-1]='\0';
         count = 0;
         return;
      }
   }



   bit_clear(pir1,5);
}

      
      
void main()
   {
   
      enable_interrupts(global);
      enable_interrupts( int_rda);
      
      for(count=0; count<=BUFFER_SIZE;count++)
      {
      rx_data[count] = '0';
      rx_data_L1[count] = '0';
      rx_data_L2[count] = '0';
      }
      count = 0;

      printf( "char Initialize = %c, char Remote = %c,  ",Initialize, Remote);
      printf( "char Stop = %c, char Request = %c ", Stop, Request);
      
      
   while(1)
      {      
         
      delay_ms(5000);
      printf( "rx_data[0] = %c\n", rx_data[0]);
      for(i=1;i<BUFFER_SIZE-1; i++)
      {
         rx_data_L1[i-1] = rx_data_L1[i];
      }
      rx_data_L1[BUFFER_SIZE-1] = '\0';
      
      printf("rxdata = %s",  rx_data_L1);
      
      
      if (mode == Ang_Arm_1)
         printf("Received data L1 is : %s\n", rx_data_L1);
      
      if (mode == Ang_Arm_2)
         printf("Received data L2 is: %s\n", rx_data_L2);
      
      
      if((mode ==Initialize)|| (mode ==Remote)||(mode ==Stop) || (mode ==Request))
         printf("Received data is mode: %c\n", mode);
      
   
   
      }
   }
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Mar 03, 2004 7:52 pm     Reply with quote

Aside from other comments, I'll just make these:

Where does your data stream come from ?

Do you design the format, or is determined by
another device and it can't be changed ?

What is the format of the incoming data stream ?
Is it entirely ASCII characters ?

Can you post a sample of the incoming data stream ?
ie., Post an example that shows all of the kinds
of data fields that you wish to parse. Show the complete
stream, including all field separators, start and end of
message characters, control characters, etc.
trevor



Joined: 03 Mar 2004
Posts: 2

View user's profile Send private message Send e-mail MSN Messenger

PostPosted: Thu Mar 04, 2004 10:40 am     Reply with quote

the data stream is supposed to come from MATLAB but for now I am testing it through Hyperterminal. the characters can be either R, S, Q, I. i also want to send two floating point numbers, but in order to distinguish them, I decided to append a character to the start the '$' for one value and the '@' for the other. the data is sent as a string with a '\n' terminator.
the following is the only possible data formats that can be sent

Initialize = I

Remote = R

Stop = S

Request = Q

Ang_Arm_1 = $90.980

Ang_Arm_1 = $-90.98

Ang_Arm_2 = @123.45

Ang_Arm_2 = @-139.5

the data for Ang_Arm_1 and Ang_Arm_2 is formatted with the start character and six characters always.

all are ternimated by the \n character.


i'm not sure if that helps. if you want anything else i will try to give more info.

thanks.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Mar 04, 2004 1:25 pm     Reply with quote

I would do this by:

1. Use an interrupt-driven software fifo to receive the incoming
RS232 characters. See the CCS example file, EX_SISR.C.
This would be the only code in the #int_rda routine.

2. In main(), I would have a while(1) loop, in which I check to see
if a char is available in the receive fifo. If so, I would call
another routine (see EX_SISR.C) to get the char from the fifo.

3. I would call each of your strings a "message". I would have a
state variable in main(), that told me whether I was "within a
message" or not. Initially, when the program starts, we are not
within a message.

4. I would then scan the incoming characters from the receive fifo,
and look for one of your special "Message start" chars.
As soon as I found one, I would put it into another buffer,
that holds an incoming message. I would set the flag that indicates
we are "within a message". I would continue to put chars
into the buffer, until I receive a "message done" char (ie., \n).
I would also check to make sure I don't overflow the message
buffer. Make it long enough to hold the longest message, plus
a couple more chars.

5. After receiving a complete message, I would call a routine to
parse the message. I would check the first char in the message
buffer, to determine how to decode the string. I would use
a switch-case statement for this (or a chain of if-else statements).

6. If the message is a floating point value, I would first over-write
the terminator character '\n' with a 0, in order to turn the message
into a string. Then I would call the atof() routine, which converts
a string into a floating point variable. Then, based on the initial
message char, '@' or '$', I would put the float into the proper
variable.


7. You have some other single-byte commands. As soon as you
receive one of those, you can execute the command.
Use a switch-case statement to parse the command byte and
call the proper routine. Within each case statement, you should
verify that other setup parameters are valid, before executing
the command. (ie., Don't let your hardware do anything that
is grossly incorrect).
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