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

newbe programing help

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








newbe programing help
PostPosted: Fri Apr 11, 2008 1:52 pm     Reply with quote

Hi all,

Here a little explanation of what I want. I have a 16F877A board with a LCD display and a RS232 port. I receive continuously some info from the RS232 port, and I want to display only one info from the RS232 stream.

Here is the RS232 stream :


    
    ADCO 050622013932 8
    OPTARIF HC.. <
    ISOUSC 45 ?
    HCHC 000000000 F
    HCHP 000000001 T
    PTEC HP..
    IINST 000 W
    IMAX 000 ?
    PAPP 00000 !
    HHPHC A ,
    MOTDETAT 000000 B


This is repeated all the time.

The line I am interested of is "HCHC 000000000 F" and especially the value "000000000" which will change of course.

I wrote a basic program, but I am not very firendly with string manipulation. Anyway here is my code for the moment :

Code:

#include <16F877.H>
#fuses XT, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP
#use delay(clock=4000000)
#use rs232(baud=1200, parity=E, bits=7, xmit=PIN_C6, rcv=PIN_C7, ERRORS)

#include "lcd.h"
#include <string.h>

#define BUFFER_SIZE 20
BYTE buffer[BUFFER_SIZE];
BYTE next_in = 0;
BYTE next_out = 0;

#int_rda
void serial_isr() {
   int t;

   buffer[next_in]=getc();
   t=next_in;
   next_in=(next_in+1) % BUFFER_SIZE;
   // Buffer full !!
   if(next_in==next_out) next_in=t; 
}

#define bkbhit (next_in!=next_out)

BYTE bgetc()
{
   BYTE c;
   while(!bkbhit) ;
   c=buffer[next_out];
   next_out=(next_out+1) % BUFFER_SIZE;
   return(c);
}

void my_get_string(char* s, unsigned int8 max)
{
  unsigned int8 len;
  char c;
  --max;
  len=0;
  do
  {
    c = bgetc() & 0x7F;   // 7 bits so force data7 to 0
    //lcd_putc(c);
    //putc(c);
    if(len<=max)
      s[len++]=c;
    else
      c=0x0D;
  } while(c!=0x0D);
  s[len]=0;
}

//===================================
void main()
{
  char input_str[BUFFER_SIZE];
  lcd_init();
  lcd_putc("\fReady...\n");
  SET_TRIS_A(0x00);
  enable_interrupts(int_rda);
  enable_interrupts(global);

  while(1)
  {
   my_get_string(input_str, BUFFER_SIZE-1);
  lcd_putc("\f");
  lcd_writestring(input_str);
   output_bit(PIN_A0, !input(PIN_A0));
  }
}


Of course this code was one of an example I modified.

Can you please have a look at this and let me know/help to do what I want ?

Thank you for your help.

Br,
Denis
Dimmu



Joined: 01 Jul 2007
Posts: 37

View user's profile Send private message

PostPosted: Fri Apr 11, 2008 2:43 pm     Reply with quote

Hi,

Here is a simple example of code that should help you. Be careful that this code is not error proof.
I tested it with a 18F97J60.

You have to initialise the function with a call to
"Rs232Init();"

The your mainloop function must call as often as possible the function
"SerialTask();"


Under interrupt :
The bytes are stored into a buffer. In case of overflow, the complete buffer is lost ( due to the WRITE pointer that reached the READ pointer. no protection here )

Main function :
If the char '\n' is found, the last line of data received is treated at once. The function "HandleCommand" reads the first word of the line and compares it with a given keyword ( here : HCHC ). If found, the rest of the line is interpreted.


Best regards,
Dimmu

Code:
#define RS232_BUFFER_SIZE  64
#define RS232_IDX_MASK     RS232_BUFFER_SIZE - 1

#include "ctype.h"
#include "string.h"
#include "stdlib.h"

struct _RS232_BUFFER_T {
   char           DATA[RS232_BUFFER_SIZE];
   unsigned int8  READ_IDX;
   unsigned int8  WRITE_IDX;
} RS232_BUFFER;



// interrupt driven data reception
// each byte is written into the buffer
// the buffer must be read BEFORE overflow !
#int_rda
void Rs232ReceiveByte ( ) {
   RS232_BUFFER.DATA[RS232_BUFFER.WRITE_IDX++] = getc();
   RS232_BUFFER.WRITE_IDX &= RS232_IDX_MASK;
}

// same as a kbhit function
int1 Rs232DataAvailable ( void ) {
   return (RS232_BUFFER.READ_IDX != RS232_BUFFER.WRITE_IDX);
}

// reads one byte from the buffer
char Rs232GetData ( void ) {
   char c;

   c = RS232_BUFFER.DATA[RS232_BUFFER.READ_IDX++];
   RS232_BUFFER.READ_IDX &= RS232_IDX_MASK;
   return c;
}

// initialisation function
// this function enables the interrupts !!
void Rs232Init ( void ) {
   // Set the wsrite IDX to 1 and clear the input buffer
   RS232_BUFFER.WRITE_IDX = 1;
   RS232_BUFFER.DATA[0]   = 0;

   // enable interrupts
   enable_interrupts ( INT_RDA );
   enable_interrupts ( GLOBAL );

   // A delay is added to clear any pending data
   // this can be removed if necessary
   delay_ms ( 100 );

   // Now clear the input buffer
   RS232_BUFFER.WRITE_IDX = 0;
   RS232_BUFFER.READ_IDX  = 0;

}


// reads a string value from the current position ( only alphanum values )
// no provision is taken to ensure that the input string
// is big enough to content the input data
// However the returned string shall never be greater than the input buffer
void GetString ( char * STR ) {
   int1  LOOP     = TRUE;
   char  c;

   while ( LOOP ) {
      if ( Rs232DataAvailable() ) {
         c = Rs232GetData();
         putc ( c );
         if ( isalnum ( c ) )
            *STR++ = c;
         else
            LOOP = FALSE;
      }
   }
   *STR = 0;
}

// skips the blank chars from a given string and returns the
// number of shar skipped
// only the blank chars are removed, not the TABS, ...
int8 SkipBlank ( char * DATA ) {
   int8 IDX = 0;
   while ( DATA[IDX] == ' ' ) {
      IDX++;
   }
   return IDX;
}

// copy the next token from string SOURCE into sting DEST
// the token is delimited by the trailing blanks
// the heading blanks are skipped
int8 CopyToken ( char * DEST, char * SOURCE ) {
   int8 IDX = 0;
   char c;

   IDX      = SkipBlank ( SOURCE );
   SOURCE  += IDX;

   while ( TRUE ) {
      c = *SOURCE++;
      if ( ( c == ' ' ) || ( c == 0 ) )
         break;

      *DEST++ = c;
      IDX++;
   }
   *DEST = 0;

   return IDX;
}


// reads the input string and handles the data
void HandleCommand ( char * DATA ) {
   char     CMD[32];
   char     VALID_CMD[5];
   int8     DATA_IDX          = 0;
   int32    VALUE;

   // copy first token of data into CMD
   // and save the current size of the token
   DATA_IDX += CopyToken ( CMD, DATA );

   strcpy ( VALID_CMD, "HCHC" );
   if ( strcmp ( VALID_CMD, CMD ) == 0 ) {
     
      // increase DATA in order to point to the next element from the string
      DATA += DATA_IDX;
      printf ( "HCHC found ==> " );
     
      // read the element ( must be the desired value )
      DATA_IDX += CopyToken ( CMD, DATA );
      printf ( "string value = %s", CMD );
     
      // convert the string into an int32 value
      VALUE = atoi32( CMD );
      printf ( " ==> numeric value = %lu \n", VALUE );
   }
}

void SerialTask ( void ) {
   static char DATA[32];
   static char IDX = 0;
   char c;

   while ( Rs232DataAvailable() ) {
      c = Rs232GetData();
      putc ( c );
      // BackSpace
      if ( c == 8 ) {
         if ( IDX != 0 )
            IDX--;
      }
      else if ( c == '\n' ) {
         DATA[IDX] = 0;
         HandleCommand( DATA );
         IDX = 0;
         DATA[0] = 0;
         // Send ACK
         putc ( 0x07 );
      }
      else if ( c == '\r' ) {
         // nothing to do !
      }
      else {
         if ( IDX < 32 ) {
            DATA[IDX++] = c;
         }
      }
   }
}
tyhon
Guest







Re: newbe programing help
PostPosted: Sat Apr 12, 2008 7:28 am     Reply with quote

[quote="Anonymous"]Hi all,

Here a little explanation of what I want. I have a 16F877A board with a LCD display and a RS232 port. I receive continuously some info from the RS232 port, and I want to display only one info from the RS232 stream.

Here is the RS232 stream
you can post circuit ?
tyhon
Guest







PostPosted: Sat Apr 12, 2008 7:30 am     Reply with quote

you can post circuit on forum?
Guest








PostPosted: Thu Apr 17, 2008 9:13 am     Reply with quote

Hi, Yes I can post the schématics, but what part do you need?

I still not had time to test the code, but hope to have time next week.
I keep you posted.

Br
Denis
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