|
|
View previous topic :: View next topic |
Author |
Message |
Ringo42
Joined: 07 May 2004 Posts: 263
|
best way to store bytes from serial port |
Posted: Mon Jul 11, 2011 1:59 pm |
|
|
I want to search for a header in a serial stream, then I just need to use the next 2 bytes. Is this the best way to do it or is there a better or faster method?
Code: | #int_rda
void serial_int_routine()
{
//Shift down all 6 bytes
header1=header2;//5A 90
header2=header3;//A5 165
header3=header4;//00 0
header4=speed1; //C0 192
speed1=speed2; //low bit
speed2=getc(); //high bit
if((header1==0x5A) && (header2==0xA5) && (header3==0x00) && (header4==0xC0))
flag=1;
} |
_________________ Ringo Davis |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19504
|
|
Posted: Mon Jul 11, 2011 2:41 pm |
|
|
The silly thing here is that though 'messy', in appearance, compared to using something like a circular buffer, it is probably faster...
However I'd say a state machine is probably the best way.
There is no point in actually storing the earlier bytes. Just have a static 'state' variable, when you see '5A' arrive change to the next state. If this then sees 'A5', change to the next state, if not, go back. Similarly if the next state sees '00', go to the next state, or back if not. Again then look for C0, and to the next state if this is seen. When you arrive at the fourth state, store the first byte and advance. Then store the second byte and set the flag. This way you only need one test for each byte (currently doing four), and the two bytes of actual data storage, plus the state variable (currently 6 bytes).
Best Wishes |
|
|
SherpaDoug
Joined: 07 Sep 2003 Posts: 1640 Location: Cape Cod Mass USA
|
|
Posted: Mon Jul 11, 2011 2:57 pm |
|
|
How about something like:
Code: |
if(getc() == '5A')
if(getc() == 'A5')
if(getc() == '00')
if(getc() == 'C0')
speed1 = getc();
speed2 = getc();
flag = 1;
|
_________________ The search for better is endless. Instead simply find very good and get the job done. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19504
|
|
Posted: Tue Jul 12, 2011 2:07 am |
|
|
The problem with that, is you are stuck inside the interrupt code, till the entire sequence is seen. Killer.....
Code: |
enum st_val {look_5A,look_A5,look_00,look_c0,store_LSB,store_MSB};
#int_rda
void serial_int_routine(void) {
static st_val state= look_5A;
int8 temp;
int1 loop;
temp=getc();
do {
loop=FALSE;
switch (state) {
case look_5A:
if (temp==0x5A) ++state;
break;
case look_A5:
if (temp==0xA5) ++state;
else {
loop=TRUE; //retest the character if not A5
state=look_5A;
}
break;
case look_00:
if (temp==0x00) ++state;
else {
loop=TRUE; //retest the character if not 00
state=look_5A;
}
break;
case look_A5:
if (temp==0xC0) ++state;
else {
loop=TRUE; //retest the character if not C0
state=look_5A;
}
break;
case store_LSB:
speed1=temp;
++state;
break;
case store_MSB:
speed2=temp;
state=look_A5;
flag=1;
break;
}
while (loop);
}
|
This fetches one character, and does just one state test, and one value test for each incoming character, unless you get to the middle of the header, and the match fails, in which case it 'retries' for the 'A5' byte.
If you look at the program 'paths' for each received character, they are short.
It could shorten further if you didn't 'retry'. 'You 'pays your money' on this....
Best Wishes |
|
|
Ringo42
Joined: 07 May 2004 Posts: 263
|
|
Posted: Tue Jul 12, 2011 9:03 am |
|
|
Thanks, I'll give it a try tonight.
Ringo _________________ Ringo Davis |
|
|
|
|
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
|