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

rs232 buffer full

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








rs232 buffer full
PostPosted: Sat Sep 09, 2006 11:51 am     Reply with quote

I have a gps in a com port.
After i received a sentence i stop the rca interrupt to make some calculations and then go back again to main program and enable the rca interrupt.

The problem is because in the time i was making the debug the buffer is full and then when i go back to the main i need to clear the rx buffer.
What is the best way to do this?

thanks
Ttelmah
Guest







PostPosted: Sat Sep 09, 2006 2:34 pm     Reply with quote

Code:

while (kbhit()) getc();
enable_interrupts(INT_RDA);

You _must_ have the 'errors' statement in your RS232 setup, which will clear the 'overrun' error status bit, when getc is called (otherwise the UART will remain disabled if this is set).
Use the 'fgetc', and 'kbhit(stream)' functions, if you have more than one serial stream.

Best Wishes
Douglas Kennedy



Joined: 07 Sep 2003
Posts: 755
Location: Florida

View user's profile Send private message AIM Address

PostPosted: Sun Sep 10, 2006 5:30 am     Reply with quote

This issue comes up often. You will most very likely need a software circular buffer fed by an #NT RDA interrupt service routine (isr).
Do very little other work inside the isr. If the pic cycle time is fast compared to the time to receive a char from your GPS then you can have code ( in the isr) to reject certain sentences from getting into your circular buffer but be very very frugal inside an isr. In your main code read from the circular buffer and do all the parsing of the sentences. Almost any other approach will bring frustration as GPS data is missed.
Guest








PostPosted: Sun Sep 10, 2006 1:19 pm     Reply with quote

Both are a good help.
Ttelmah is the answer for my question but i make a search about circular buffer and i see that it is a good way to not loose any data.
but how can i do it?
imagine that i read data from the gps, send to the buffer and then send to the pc the complete sentence.
i see some posts about circular buffers but i dont know what to do...
I understand interrupt function but i dont understand how to treat the circular buffer...

any help?

thanks
Douglas Kennedy



Joined: 07 Sep 2003
Posts: 755
Location: Florida

View user's profile Send private message AIM Address

PostPosted: Sun Sep 10, 2006 5:38 pm     Reply with quote

This is not a complete program but you will see there is a circular buffer gps_buff. Two pointers to the buffer are maintained one is the next available position for a char from the GPS to occupy and the other is the last char the main program read. The buffer is said to be circular because when the gps fills the last slot it rolls over and starts from the first slot.
Now of course your code should be reading fast enough to keep the GPS from getting a head and writing over chars your main program hasn't yet read. Buffer size of 64 should be adequate
The getc() you may be familiar with is replaced by gps_getc() for the purpose of the main program getting chars from the gps_buff.

I can't recommend more strongly the lessons learned by hacking through these issues yourself. The sentence filter is removed from the isr. It could be a good exercise to add your own if you need it.
This code was modified from PCM programmers example of a circular buffer that I found very informative several years back. I've included a structure since they are both descriptive and useful in reducing possible confusion of the position of the terms in GPS sentences. The code originally read from the GPS several different sentences and extracted and converted the info into the structure you see below

Code:
struct {
/// status 'A' ok 'V' gps has problem (Ex.loss of signal ) 'X' invalid period
char  gll_status;
float gll_lat;
char  gll_N_S;
float gll_long;
char  gll_E_W;
char  xte_status;
float xte_error;
char  xte_steer;
char  bwc_status;
char  bwc_utc[6];
float bwc_lat;
char  bwc_N_S;
float bwc_long;
char  bwc_E_W;
float bwc_bearing_true;
float bwc_bearing_mag;
float bwc_dist;
} gps; // note a one byte CRC is appended upon transmission
       // gps is sent plus a CRC by the isr

short int led2_flag,sentence,PARSING;
byte seconds=0,int_count=0,I2C_CRC=0,GPS_CRC=0;
byte gps_buff[BUFFER_SIZE]; // implemented as a circular buffer

int next_gps_ptr=0,last_read_ptr=0,offset=0,temp;

#int_rda
void gps_isr()
{
char c;
/// will only allow $GPXTE and $GPGLL and $GPBWC data into gps_buff
/// filter will screen $GPXT $GPGL $GPBW
/// note this routine needs to as short as possible since it is called
/// for each char received from GPS

c=getc() ; // get data
if (c=='$') { sentence=true;output_low(LED1);return;} // new sentence

if(sentence){

      gps_buff[next_gps_ptr]=c;
      if (++next_gps_ptr>sizeof(gps_buff)) next_gps_ptr=0; // circular  buffer
      if((c==10)||(c==13)) {sentence=false;output_high(LED1);}

            }

}

int gps_getc()
{
char c;
int next_char_ptr;
next_char_ptr=last_read_ptr+1;
if (next_char_ptr>sizeof(gps_buff))next_char_ptr=0;


// there is data available if next_gps_ptr != next_char_ptr

wait:  // data from gps will allow isr to update gps_ptr

if (next_gps_ptr == next_char_ptr) goto wait; // let gps advance
else        {
             c=gps_buff[next_char_ptr];
             if(c=='*')PARSING=false; // PARSING is reset in main loop
             last_read_ptr=next_char_ptr;
             if (PARSING) GPS_CRC=GPS_CRC ^ c; // calc between $ and *
            }
return(c);
}
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