gps 数据解析和数据提取代码
时间:10-02
整理:3721RD
点击:
以下提供的是实现方法,根据开发环境不同可能需要做一定的修改。下面代码是鄙人成功验证后截取的几个重要部分,仅供参考。
oa_char * nmea_0183_parsing(oa_char * buf/*UART_rx*/, int buf_len, oa_char *symbol, oa_char block, oa_char block_num);
oa_int32 nmea_ascii_to_hex(oa_char * pt, oa_char * pd);
#define GPRMC "$GPRMC"
#define GPGSV "$GPGSV"
#define GPGGA "$GPGGA"
#define GPGSA "$GPGSA"
/*nmea数据变换*/
oa_int32 nmea_ascii_to_hex(oa_char * pt, oa_char * pd)
{
oa_char ascii[15]= {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
oa_int32 tmp =0;
oa_meMCPy(&ascii, pt, pd-pt);
// if(debug_printf) OA_DEBUG_USER(" %s(ascii=%s)\n", __func__, ascii);
tmp = oa_atoi((oa_char*)&ascii); /*字符数据变换int*/
// if(debug_printf) OA_DEBUG_USER(" %s(tmp=%ld)\n", __func__, tmp);
return (tmp);
}
// $GPGGA,<1>,<2>,<3>,<4>,<5>,<6>,<7>,<8>,<9>,<10>,<11>,<12>,<13>,<14>*<15><CR><LF>
// $GPGSA,<1>,<2>,<3>,<4>,<5>,<6>,<7>,<8>,<9>,<10>,<11>,<12>,<13>,<14>,<15>,<16>,<17>*<18><CR><LF>
// $GPGSV, <1>,<2>,<3>,<4>,<5>,<6>,<7>,...,<4>,<5>,<6>,<7>*<8><CR><LF>
// $GPRMC,<1>,<2>,<3>,<4>,<5>,<6>,<7>,<8>,<9>,<10>,<11>,<12>*<13><CR><LF>
// $GPVTG,<1>,T,<2>,M,<3>,N,<4>,K,<5>*hh
oa_char * nmea_0183_parsing(oa_char * buf/*串口数据指针*/, int buf_len/*串口数据长度*/, oa_char *symbol/*提取字符输入的字符串,如 "$GPRMC"*/, oa_char block/*提取字符串中数据位置,如"$GPRMC"中 <3>数据*/, oa_char block_num/*字符串中数据的最大成员数,如 $GPRMC中是13*/)
{
oa_char i=0,*pp=0,*np;
int len;
oa_char text[15]= {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
// OA_DEBUG_USER(" %s(%s)<%d>\n", __func__, symbol, block);
len=0;
do {
if(!oa_strncmp(buf+len, symbol, 6))/*比较字符*/
{
pp = buf + len + 6;
// if(debug_printf) OA_DEBUG_USER(" %s(%s)\n", __func__, pp);
for(i=1;i<= block_num; i++)
{
np = oa_strchr(pp, ',');/*获得分隔符,指针*/
pp = np+1;
if((np != NULL) && (*(pp)/*next ,*/ != ',') && (i==block))
{
if(debug_printf)
{
oa_memcpy(&text, np, oa_strchr(pp, ',')-np+1);
OA_DEBUG_USER(" %s(%s)<%d>(s=%s)\n", __func__, symbol, block, text/*np*/);
}
return(pp);/*返回数据指针*/
}
}
}
len++;
}while(len < buf_len);
return (0);
}
举例代码1:
prx= nmea_0183_parsing(nmea/*串口接收数据指针*/, len/*=200*/, GPRMC/*提取字符组*/, 2/*选择<2>数据*/, 12/*<?>成员最大数*/);
if(prx!=0)
{
if (*prx == 'A' || *prx =='a' || *prx == 'V' || *prx== 'v' )/*A=有效定位,V=无效定位*/
{
//gps_state = *prx;
}
else
{
//gps_state = 0;
}
}
//else gps_state = 0;
举例代码2:
// 6, 速度
char * ptx;
prx= nmea_0183_parsing(nmea/*rx*/, len/*rx len建议大于200*/, GPRMC, 7/*select <7>速度*/, 12/*, separator num*/);
if(prx!=0)
{
// 取值范围000.0~999.9节
double fp=0;
char * dot;
dot = oa_strchr(prx, '.');
if(dot < oa_strchr(prx, ',') )
{
fp=(float)(nmea_ascii_to_hex(prx, dot)*1.852);//浮点数整数处理
prx = dot + 1;/*.*/
}
//fp = fp + (float)(nmea_ascii_to_hex(prx, oa_strchr(prx, ',')))*1.852;/*1节=1.852KM/小时,浮点数小数处理,需要完善*/
gps_speed= (unsigned short int)(fp);/*1节=1.852KM/小时*/
if(debug_printf) OA_DEBUG_USER(" %s(fp=%lf)\n", __func__, fp);
}
else gps_speed =0;
oa_char * nmea_0183_parsing(oa_char * buf/*UART_rx*/, int buf_len, oa_char *symbol, oa_char block, oa_char block_num);
oa_int32 nmea_ascii_to_hex(oa_char * pt, oa_char * pd);
#define GPRMC "$GPRMC"
#define GPGSV "$GPGSV"
#define GPGGA "$GPGGA"
#define GPGSA "$GPGSA"
/*nmea数据变换*/
oa_int32 nmea_ascii_to_hex(oa_char * pt, oa_char * pd)
{
oa_char ascii[15]= {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
oa_int32 tmp =0;
oa_meMCPy(&ascii, pt, pd-pt);
// if(debug_printf) OA_DEBUG_USER(" %s(ascii=%s)\n", __func__, ascii);
tmp = oa_atoi((oa_char*)&ascii); /*字符数据变换int*/
// if(debug_printf) OA_DEBUG_USER(" %s(tmp=%ld)\n", __func__, tmp);
return (tmp);
}
// $GPGGA,<1>,<2>,<3>,<4>,<5>,<6>,<7>,<8>,<9>,<10>,<11>,<12>,<13>,<14>*<15><CR><LF>
// $GPGSA,<1>,<2>,<3>,<4>,<5>,<6>,<7>,<8>,<9>,<10>,<11>,<12>,<13>,<14>,<15>,<16>,<17>*<18><CR><LF>
// $GPGSV, <1>,<2>,<3>,<4>,<5>,<6>,<7>,...,<4>,<5>,<6>,<7>*<8><CR><LF>
// $GPRMC,<1>,<2>,<3>,<4>,<5>,<6>,<7>,<8>,<9>,<10>,<11>,<12>*<13><CR><LF>
// $GPVTG,<1>,T,<2>,M,<3>,N,<4>,K,<5>*hh
oa_char * nmea_0183_parsing(oa_char * buf/*串口数据指针*/, int buf_len/*串口数据长度*/, oa_char *symbol/*提取字符输入的字符串,如 "$GPRMC"*/, oa_char block/*提取字符串中数据位置,如"$GPRMC"中 <3>数据*/, oa_char block_num/*字符串中数据的最大成员数,如 $GPRMC中是13*/)
{
oa_char i=0,*pp=0,*np;
int len;
oa_char text[15]= {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
// OA_DEBUG_USER(" %s(%s)<%d>\n", __func__, symbol, block);
len=0;
do {
if(!oa_strncmp(buf+len, symbol, 6))/*比较字符*/
{
pp = buf + len + 6;
// if(debug_printf) OA_DEBUG_USER(" %s(%s)\n", __func__, pp);
for(i=1;i<= block_num; i++)
{
np = oa_strchr(pp, ',');/*获得分隔符,指针*/
pp = np+1;
if((np != NULL) && (*(pp)/*next ,*/ != ',') && (i==block))
{
if(debug_printf)
{
oa_memcpy(&text, np, oa_strchr(pp, ',')-np+1);
OA_DEBUG_USER(" %s(%s)<%d>(s=%s)\n", __func__, symbol, block, text/*np*/);
}
return(pp);/*返回数据指针*/
}
}
}
len++;
}while(len < buf_len);
return (0);
}
举例代码1:
prx= nmea_0183_parsing(nmea/*串口接收数据指针*/, len/*=200*/, GPRMC/*提取字符组*/, 2/*选择<2>数据*/, 12/*<?>成员最大数*/);
if(prx!=0)
{
if (*prx == 'A' || *prx =='a' || *prx == 'V' || *prx== 'v' )/*A=有效定位,V=无效定位*/
{
//gps_state = *prx;
}
else
{
//gps_state = 0;
}
}
//else gps_state = 0;
举例代码2:
// 6, 速度
char * ptx;
prx= nmea_0183_parsing(nmea/*rx*/, len/*rx len建议大于200*/, GPRMC, 7/*select <7>速度*/, 12/*, separator num*/);
if(prx!=0)
{
// 取值范围000.0~999.9节
double fp=0;
char * dot;
dot = oa_strchr(prx, '.');
if(dot < oa_strchr(prx, ',') )
{
fp=(float)(nmea_ascii_to_hex(prx, dot)*1.852);//浮点数整数处理
prx = dot + 1;/*.*/
}
//fp = fp + (float)(nmea_ascii_to_hex(prx, oa_strchr(prx, ',')))*1.852;/*1节=1.852KM/小时,浮点数小数处理,需要完善*/
gps_speed= (unsigned short int)(fp);/*1节=1.852KM/小时*/
if(debug_printf) OA_DEBUG_USER(" %s(fp=%lf)\n", __func__, fp);
}
else gps_speed =0;
