|
|
View previous topic :: View next topic |
Author |
Message |
Guest
|
newbe programing help |
Posted: Fri Apr 11, 2008 1:52 pm |
|
|
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
|
|
Posted: Fri Apr 11, 2008 2:43 pm |
|
|
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 |
Posted: Sat Apr 12, 2008 7:28 am |
|
|
[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
|
|
Posted: Sat Apr 12, 2008 7:30 am |
|
|
you can post circuit on forum? |
|
|
Guest
|
|
Posted: Thu Apr 17, 2008 9:13 am |
|
|
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 |
|
|
|
|
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
|