EmbeddedRelated.com
Forums

Re: Request for Help with hcs12 microcontroller!

Started by mukul tewary March 19, 2009
Hi all,
I just signed up for this group.. I needed to ask someone for some help.. I am working on a project, and a part of it requires me to take information that is being sent in from a GPS device and parse the string to extract the latitude and longitude coordinates and send it serially to a laptop connected via the second serial port.. The GPS device unfortunately can't be controlled to send information when I need it, it does it all the time.. But it is of a certain format, I think I should be able to extract the information once I have it stored in some location.. but I've been told (..and it makes complete sense) that I can't use the 'file' C-commands in the micro-controller.. so now i guess what needs to be done is for me to design a buffer for the incoming information and keep re-writing on it until I am ready to take the information from it, but I can't figure out the code for that to save my life! :/ haha..
Can someone please give me a (even if its rudimentary) piece of code that can get me on my way? Also, If I have the logic that needs to be used all wrong, can someone please help me out with that too?

Thank you all very very much! Sorry for the bother..

I will truly appreciate any help, and tons of apologies for spamming everyone!

warm regards,
Mukul

Hello Mukul;

Because of the unknown relationship between the
filling from the GPS and the query from the laptop
you will need a double buffer. This second buffer
will be updated immediately after the GPS sends
its data and will supply the LAT /LON to the laptop.

Greg

mukul tewary wrote:
> Hi all,
> I just signed up for this group.. I needed to ask someone for some
> help.. I am working on a project, and a part of it requires me to take
> information that is being sent in from a GPS device and parse the
> string to extract the latitude and longitude coordinates and send it
> serially to a laptop connected via the second serial port.. The GPS
> device unfortunately can't be controlled to send information when I
> need it, it does it all the time.. But it is of a certain format, I
> think I should be able to extract the information once I have it
> stored in some location.. but I've been told (..and it makes complete
> sense) that I can't use the 'file' C-commands in the
> micro-controller.. so now i guess what needs to be done is for me to
> design a buffer for the incoming information and keep re-writing on it
> until I am ready to take the information from it, but I can't figure
> out the code for that to save my life! :/ haha..
> Can someone please give me a (even if its rudimentary) piece of code
> that can get me on my way? Also, If I have the logic that needs to be
> used all wrong, can someone please help me out with that too?
>
> Thank you all very very much! Sorry for the bother..
>
> I will truly appreciate any help, and tons of apologies for spamming
> everyone!
>
> warm regards,
> Mukul

Hi, Mukul,

I use a 68HC11 to read the data from a GPS receiver. Below is the
code I use to do this. It should work with little change for a
68HC12. I use a Motorola Oncore receiver, which sends out a
time-position sentence in a Motorola binary format. The first four
characters of the sentence are "@@Hb", followed by the time,
latitude, longitude, altitude, and a few other items, followed by a
check sum and a CR LF. When the HC11 receives a new byte, an
interrupt is generated, and in the ISR, I look for the sequence
"@@Hb", then fill a buffer with the rest of the data, calculate the
check sum and compare it to the check sum sent by the GPS, and read
the trailing CR LF. After I am satisfied that I have received a
complete sentence, I extract the time and position out of the
sentence.
While my code works only for Motorola format data, it should be easy
to adapt for other forms, such as NMEA.

Below is the relevant part of the code. I hope this helps.

Bill

#include
#include

#define TRUE 1
#define FALSE 0

#define S1 1 /* Wait for first @ */
#define S2 2 /* Wait for second @ */
#define S3 3 /* Wait for H */
#define S4 4 /* Wait for b */
#define S5 5 /* Read position-time message */
#define S6 6 /* Get check-sum for position-time message */
#define S7 7 /* Get CR for position-time message */
#define S8 8 /* Get LF for position-time message */

#define RUNNING 7 /*these values define flags used by the */
#define COMPLETE 8 /*sci isr */
#define ERROR 9 /* */

#define ID1 'H' /*motorola packet id 'H' */
#define ID2 'b' /* 12-channel position-time message */
#define CR 0x0d /*ascii carrage return - framing char */
#define LF 0x0a /*ascii line feed - framing char */
#define PS12_LEN 54 /*length of the motorola data packet to save */
#define YEAR_POS_1 6 /*position of the hour info in packet */
#define YEAR_POS_2 7 /*position of the hour info in packet */
#define MONTH_POS 4 /*position of the hour info in packet */
#define DAY_POS 5 /*position of the hour info in packet */
#define HOUR_POS 8 /*position of the hour info in packet */
#define MIN_POS 9 /*position of the minute info in packet */
#define SEC_POS 10 /*position of the second info in packet */
#define LAT4_POS 15 /*position of the latitude info in packet */
#define LAT3_POS 16 /*position of the latitude info in packet */
#define LAT2_POS 17 /*position of the latitude info in packet */
#define LAT1_POS 18 /*position of the latitude info in packet */
#define LNG4_POS 19 /*position of the longitude info in packet */
#define LNG3_POS 20 /*position of the longitude info in packet */
#define LNG2_POS 21 /*position of the longitude info in packet */
#define LNG1_POS 22 /*position of the longitude info in packet */
#define ALT4_POS 23 /*position of the GPS altitude info in packet */
#define ALT3_POS 24 /*position of the GPS altitude info in packet */
#define ALT2_POS 25 /*position of the GPS altitude info in packet */
#define ALT1_POS 26 /*position of the GPS altitude info in packet */

void initialize(void);
void decode_gps(void);
void sci_isr(void);

/*global vars for the gps decoder*/
unsigned char status, state, count;
unsigned char year, month, day, hour, min, sec;
unsigned char chk_sum_calc_ps12, chk_sum_rcvd_ps12;
unsigned char lat_4,lat_3,lat_2,lat_1,lng_4,lng_3,lng_2,lng_1,alt_4,alt_3,
alt_2,alt_1;
unsigned char rpt_buf[PC12_LEN]; /* motorola data packet array */
main(void)
{
initialize(); /*initialize everything*/

enable(); /* enable interrupts */

state = S1;
status = RUNNING;

while(1)
{
/* Do whatever needs to be done to send data to host */
}
}
/*initialize - function to do all necessary initialization for the program
Global vars used: all globals initialized
*/
void initialize(void)
{

/*setup the SCI*/
SCCR1 = 0x00; /*1 start, 8 data, 1 stop*/
SCCR2 = 0x2c; /*Enable xmtr and rcvr, interrupt on RDRF */
BAUD = 0x30; /*9600 baud*/
}

/*decode_gps - function to retrieve time info from data buffer and
check for valid data. if data is not valid, last vaild
time is incrimented one second
Global vars used: rpt_buf[], status
*/
void decode_gps(void)
{
short full_year;

full_year = (rpt_buf[YEAR_POS_1]<<8) | rpt_buf[YEAR_POS_2];
year = full_year % 100;
month = rpt_buf[MONTH_POS]; /*grab month data*/
day = rpt_buf[DAY_POS]; /*grab day data*/
hour = rpt_buf[HOUR_POS]; /*grab hour data*/
min = rpt_buf[MIN_POS]; /*grab minute data*/
sec = rpt_buf[SEC_POS]; /*grab second data*/
lat_4 = rpt_buf[LAT4_POS];
lat_3 = rpt_buf[LAT3_POS];
lat_2 = rpt_buf[LAT2_POS];
lat_1 = rpt_buf[LAT1_POS];
lng_4 = rpt_buf[LNG4_POS];
lng_3 = rpt_buf[LNG3_POS];
lng_2 = rpt_buf[LNG2_POS];
lng_1 = rpt_buf[LNG1_POS];
alt_4 = rpt_buf[ALT4_POS];
alt_3 = rpt_buf[ALT3_POS];
alt_2 = rpt_buf[ALT2_POS];
alt_1 = rpt_buf[ALT1_POS];
vel_4 = rpt_buf[VEL4_POS];
vel_3 = rpt_buf[VEL3_POS];
vel_2 = rpt_buf[VEL2_POS];
vel_1 = rpt_buf[VEL1_POS];
hdg_2 = rpt_buf[HDG2_POS];
hdg_1 = rpt_buf[HDG1_POS];
vis = rpt_buf[VIS_POS];
track = rpt_buf[TRACK_POS];
stat_2 = rpt_buf[STAT2_POS];
stat_1 = rpt_buf[STAT1_POS];
}

#pragma interrupt_handler sci_isr

/*sci_isr - interrupt handler to scan in data from the motorola oncore
gps reciever. this isr also checks the framing of the packet
and verifies the checksum.
Global vars used: status, count, state, this_byte, rpt_buf[],
chk_sum_calc, chk_sum_rcvd
*/
void sci_isr(void)
{
unsigned char this_byte;

this_byte = SCSR;
this_byte = SCDR; /*clear the SCI flag, and grab the data*/

switch (state)
{
/*state S1 waits for an '@' in the data then continues*/
case S1:
if (this_byte == '@') state = S2;
break;

/*state S2 represents having the first '@'. it waits for
another then continues*/
case S2:
if (this_byte == '@') state = S3;
else state = S1;
break;

/*state S3 represents having the second '@'. at this point, both leading
framing characters have been seen. S3 now waits for the first id*/
case S3:
if(this_byte == ID1) state = S4;
else if(this_byte == '@') state = S3;
else state = S1;
break;

/*state S4 represents having the two framing chars and the first id.
it now waits for the second id then continues*/
case S4:
if(this_byte == ID2)
{
rpt_buf[0] = '@';
rpt_buf[1] = '@';
rpt_buf[2] = ID1;
rpt_buf[3] = ID2;
count = 4;
chk_sum_calc_ps12 = (ID1 ^ ID2);
state = S5;
}
else if (this_byte == '@') state = S2;
else state = S1;
break;

/*state S5 rpresents having the packet identified. the packet data is then
scanned in until all needed data is saved in the receive buffer */

case S5:
rpt_buf[count++] = this_byte;
chk_sum_calc_ps12 ^= this_byte;
if(count > PS12_LEN-4) /* All data except check sum, CR, LF */
state = S6;
break;

/* state S6 represents receiving the check sum */
case S6:
rpt_buf[count++] = this_byte;
chk_sum_rcvd_ps12 = this_byte;
state = S7;
break;

/* state S7 represents receiving the trailing CR */
case S7:
if (this_byte == CR)
{
state = S8;
count++;
}
else
{
status = ERROR;
count = 0;
state = S1;
}
break;

/*state S8 - represents receiving the trailing LF */
/* Save time. If time is a multiple of 12, save gps_info */
case S8:
count = 0;
state = S1;
if(this_byte == LF) status = COMPLETE;
else status = ERROR;
decode_gps();
break;

}
--- In 6..., mukul tewary wrote:
> Hi all,
> I just signed up for this group.. I needed to ask someone for some help.. I am working on a project, and a part of it requires me to take information that is being sent in from a GPS device and parse the string to extract the latitude and longitude coordinates and send it serially to a laptop connected via the second serial port.. The GPS device unfortunately can't be controlled to send information when I need it, it does it all the time.. But it is of a certain format, I think I should be able to extract the information once I have it stored in some location.. but I've been told (..and it makes complete sense) that I can't use the 'file' C-commands in the micro-controller.. so now i guess what needs to be done is for me to design a buffer for the incoming information and keep re-writing on it until I am ready to take the information from it, but I can't figure out the code for that to save my life! :/ haha..
> Can someone please give me a (even if its rudimentary) piece of code that can get me on my way? Also, If I have the logic that needs to be used all wrong, can someone please help me out with that too?
>
> Thank you all very very much! Sorry for the bother..
>
> I will truly appreciate any help, and tons of apologies for spamming everyone!
>
> warm regards,
> Mukul
>