一、文件结构
1、./include/nmea/ 头文件
config.h
context.h
generate.h
generator.h
gmath.h
info.h
nmea.h
parse.h
parser.h
sentence.h
time.h
tok.h
units.h
2、./src c文件
context.c
generate.c
generator.c
gmath.c
parse.c
parser.c
sentence.c
time.c
tok.c
3、./samples 如何使用
generate
generator
math
parse
parse_file
二、熟悉主要函数和结构体
1、info.h
typedef struct _nmeaPOS
{
double lat; /**< Latitude */
double lon; /**< Longitude */
} nmeaPOS;
/**
* Information about satellite
* @see nmeaSATINFO
* @see nmeaGPGSV
*/
typedef struct _nmeaSATELLITE
{
int id; /**< Satellite PRN number */
int in_use; /**< Used in position fix */
int elv; /**< Elevation in degrees, 90 maximum */
int azimuth; /**< Azimuth, degrees from true north, 000 to 359 */
int sig; /**< Signal, 00-99 dB */
} nmeaSATELLITE;
/**
* Information about all satellites in view
* @see nmeaINFO
* @see nmeaGPGSV
*/
typedef struct _nmeaSATINFO
{
int inuse; /**< Number of satellites in use (not those in view) */
int inview; /**< Total number of satellites in view */
nmeaSATELLITE sat[NMEA_MAXSAT]; /**< Satellites information */
} nmeaSATINFO;
/**
* Summary GPS information from all parsed packets,
* used also for generating NMEA stream
* @see nmea_parse
* @see nmea_GPGGA2info, nmea_...2info
*/
typedef struct _nmeaINFO
{
int smask; /**< Mask specifying types of packages from which data have been obtained */
nmeaTIME utc; /**< UTC of position */
int sig; /**< GPS quality indicator (0 = Invalid; 1 = Fix; 2 = Differential, 3 = Sensitive) */
int fix; /**< Operating mode, used for navigation (1 = Fix not available; 2 = 2D; 3 = 3D) */
double PDOP; /**< Position Dilution Of Precision */
double HDOP; /**< Horizontal Dilution Of Precision */
double VDOP; /**< Vertical Dilution Of Precision */
double lat; /**< Latitude in NDEG - +/-[degree][min].[sec/60] */
double lon; /**< Longitude in NDEG - +/-[degree][min].[sec/60] */
double elv; /**< Antenna altitude above/below mean sea level (geoid) in meters */
double speed; /**< Speed over the ground in kilometers/hour */
double direction; /**< Track angle in degrees True */
double declination; /**< Magnetic variation degrees (Easterly var. subtracts from true course) */
nmeaSATINFO satinfo; /**< Satellites information */
} nmeaINFO;
2、paser.h
typedef struct _nmeaPARSER
{
void *top_node;
void *end_node;
unsigned char *buffer;
int buff_size;
int buff_use;
} nmeaPARSER;
int nmea_parser_init(nmeaPARSER *parser);
void nmea_parser_destroy(nmeaPARSER *parser);
int nmea_parse(
nmeaPARSER *parser,
const char *buff, int buff_sz,
nmeaINFO *info
);
/*
* low level
*/
int nmea_parser_push(nmeaPARSER *parser, const char *buff, int buff_sz);
int nmea_parser_top(nmeaPARSER *parser);
int nmea_parser_pop(nmeaPARSER *parser, void **pack_ptr);
int nmea_parser_peek(nmeaPARSER *parser, void **pack_ptr);
int nmea_parser_drop(nmeaPARSER *parser);
int nmea_parser_buff_clear(nmeaPARSER *parser);
int nmea_parser_queue_clear(nmeaPARSER *parser);
3、parser.c
typedef struct _nmeaParserNODE
{
int packType;
void *pack;
struct _nmeaParserNODE *next_node;
} nmeaParserNODE;
4、parse.h
int nmea_pack_type(const char *buff, int buff_sz);
int nmea_find_tail(const char *buff, int buff_sz, int *res_crc);
int nmea_parse_GPGGA(const char *buff, int buff_sz, nmeaGPGGA *pack);
int nmea_parse_GPGSA(const char *buff, int buff_sz, nmeaGPGSA *pack);
int nmea_parse_GPGSV(const char *buff, int buff_sz, nmeaGPGSV *pack);
int nmea_parse_GPRMC(const char *buff, int buff_sz, nmeaGPRMC *pack);
int nmea_parse_GPVTG(const char *buff, int buff_sz, nmeaGPVTG *pack);
void nmea_GPGGA2info(nmeaGPGGA *pack, nmeaINFO *info);
void nmea_GPGSA2info(nmeaGPGSA *pack, nmeaINFO *info);
void nmea_GPGSV2info(nmeaGPGSV *pack, nmeaINFO *info);
void nmea_GPRMC2info(nmeaGPRMC *pack, nmeaINFO *info);
void nmea_GPVTG2info(nmeaGPVTG *pack, nmeaINFO *info);
5、sentence.h
enum nmeaPACKTYPE
{
GPNON = 0x0000, /**< Unknown packet type. */
GPGGA = 0x0001, /**< GGA - Essential fix data which provide 3D location and accuracy data. */
GPGSA = 0x0002, /**< GSA - GPS receiver operating mode, SVs used for navigation, and DOP values. */
GPGSV = 0x0004, /**< GSV - Number of SVs in view, PRN numbers, elevation, azimuth & SNR values. */
GPRMC = 0x0008, /**< RMC - Recommended Minimum Specific GPS/TRANSIT Data. */
GPVTG = 0x0010 /**< VTG - Actual track made good and speed over ground. */
};
/**
* GGA packet information structure (Global Positioning System Fix Data)
*/
typedef struct _nmeaGPGGA
{
nmeaTIME utc; /**< UTC of position (just time) */
double lat; /**< Latitude in NDEG - [degree][min].[sec/60] */
char ns; /**< [N]orth or [S]outh */
double lon; /**< Longitude in NDEG - [degree][min].[sec/60] */
char ew; /**< [E]ast or [W]est */
int sig; /**< GPS quality indicator (0 = Invalid; 1 = Fix; 2 = Differential, 3 = Sensitive) */
int satinuse; /**< Number of satellites in use (not those in view) */
double HDOP; /**< Horizontal dilution of precision */
double elv; /**< Antenna altitude above/below mean sea level (geoid) */
char elv_units; /**< [M]eters (Antenna height unit) */
double diff; /**< Geoidal separation (Diff. between WGS-84 earth ellipsoid and mean sea level. '-' = geoid is below WGS-84 ellipsoid) */
char diff_units; /**< [M]eters (Units of geoidal separation) */
double dgps_age; /**< Time in seconds since last DGPS update */
int dgps_sid; /**< DGPS station ID number */
} nmeaGPGGA;
/**
* GSA packet information structure (Satellite status)
*/
typedef struct _nmeaGPGSA
{
char fix_mode; /**< Mode (M = Manual, forced to operate in 2D or 3D; A = Automatic, 3D/2D) */
int fix_type; /**< Type, used for navigation (1 = Fix not available; 2 = 2D; 3 = 3D) */
int sat_prn[NMEA_MAXSAT]; /**< PRNs of satellites used in position fix (null for unused fields) */
double PDOP; /**< Dilution of precision */
double HDOP; /**< Horizontal dilution of precision */
double VDOP; /**< Vertical dilution of precision */
} nmeaGPGSA;
/**
* GSV packet information structure (Satellites in view)
*/
typedef struct _nmeaGPGSV
{
int pack_count; /**< Total number of messages of this type in this cycle */
int pack_index; /**< Message number */
int sat_count; /**< Total number of satellites in view */
nmeaSATELLITE sat_data[NMEA_SATINPACK];
} nmeaGPGSV;
/**
* RMC packet information structure (Recommended Minimum sentence C)
*/
typedef struct _nmeaGPRMC
{
nmeaTIME utc; /**< UTC of position */
char status; /**< Status (A = active or V = void) */
double lat; /**< Latitude in NDEG - [degree][min].[sec/60] */
char ns; /**< [N]orth or [S]outh */
double lon; /**< Longitude in NDEG - [degree][min].[sec/60] */
char ew; /**< [E]ast or [W]est */
double speed; /**< Speed over the ground in knots */
double direction; /**< Track angle in degrees True */
double declination; /**< Magnetic variation degrees (Easterly var. subtracts from true course) */
char declin_ew; /**< [E]ast or [W]est */
char mode; /**< Mode indicator of fix type (A = autonomous, D = differential, E = estimated, N = not valid, S = simulator) */
} nmeaGPRMC;
/**
* VTG packet information structure (Track made good and ground speed)
*/
typedef struct _nmeaGPVTG
{
double dir; /**< True track made good (degrees) */
char dir_t; /**< Fixed text 'T' indicates that track made good is relative to true north */
double dec; /**< Magnetic track made good */
char dec_m; /**< Fixed text 'M' */
double spn; /**< Ground speed, knots */
char spn_n; /**< Fixed text 'N' indicates that speed over ground is in knots */
double spk; /**< Ground speed, kilometers per hour */
char spk_k; /**< Fixed text 'K' indicates that speed over ground is in kilometers/hour */
} nmeaGPVTG;
void nmea_zero_GPGGA(nmeaGPGGA *pack);
void nmea_zero_GPGSA(nmeaGPGSA *pack);
void nmea_zero_GPGSV(nmeaGPGSV *pack);
void nmea_zero_GPRMC(nmeaGPRMC *pack);
void nmea_zero_GPVTG(nmeaGPVTG *pack);
6、tock.h
int nmea_calc_crc(const char *buff, int buff_sz);
int nmea_atoi(const char *str, int str_sz, int radix);
double nmea_atof(const char *str, int str_sz);
int nmea_printf(char *buff, int buff_sz, const char *format, ...);
int nmea_scanf(const char *buff, int buff_sz, const char *format, ...);
三、过程详解
以GPRMC为线索从main( )函数往下追踪,其过程为,准备一个接收NEMA接收数组buff[ ],一个存放解析后数据的info并初始化,一个解析结构体parser并初始化,调用 nmea_parse( )提取内容到info。
./samples/parse/main.c内容如下:
#include <nmea/nmea.h>
#include <string.h>
int main()
{
const char *buff[] = {
"$GPRMC,173843,A,3349.896,N,11808.521,W,000.0,360.0,230108,013.4,E*69\r\n",
"$GPGGA,111609.14,5001.27,N,3613.06,E,3,08,0.0,10.2,M,0.0,M,0.0,0000*70\r\n",
"$GPGSV,2,1,08,01,05,005,80,02,05,050,80,03,05,095,80,04,05,140,80*7f\r\n",
"$GPGSV,2,2,08,05,05,185,80,06,05,230,80,07,05,275,80,08,05,320,80*71\r\n",
"$GPGSA,A,3,01,02,03,04,05,06,07,08,00,00,00,00,0.0,0.0,0.0*3a\r\n",
"$GPRMC,111609.14,A,5001.27,N,3613.06,E,11.2,0.0,261206,0.0,E*50\r\n",
"$GPVTG,217.5,T,208.8,M,000.00,N,000.01,K*4C\r\n"
};
int it;
nmeaINFO info; //在info.h定义
nmeaPARSER parser; //在parser.h定义
nmea_zero_INFO(&info);
nmea_parser_init(&parser);
for(it = 0; it < 6; ++it)
`nmea_parse(&parser, buff[it], (int)strlen(buff[it]), &info);
nmea_parser_destroy(&parser); //必须和nmea_parser_init(&parser);成对使用,否则会内存泄漏
return 0;
}
以GPRMC为例,其过程为:
1、mai.c中
for(it = 0; it < 6; ++it)
nmea_parse(&parser, buff[it], (int)strlen(buff[it]), &info);
2、parser.c中:nmea_parse()
①调用nmea_parser_push(parser, buff, buff_sz)= =》nmea_parser_real_push()= =》(parse.c) nmea_parse_GPRMC( )= =》(tok.c) nmea_scanf( )
②调用nmea_parser_pop(parser, &pack)
③调用(parse.c) nmea_GPRMC2info((nmeaGPRMC *)pack, info)
int nmea_parse( nmeaPARSER *parser, const char *buff, int buff_sz, nmeaINFO *info )
{
int ptype, nread = 0;
void *pack = 0;
NMEA_ASSERT(parser && parser->buffer);
nmea_parser_push(parser, buff, buff_sz);
while(GPNON != (ptype = nmea_parser_pop(parser, &pack)))
{
nread++;
switch(ptype)
{
case GPGGA:
nmea_GPGGA2info((nmeaGPGGA *)pack, info);
break;
case GPGSA:
nmea_GPGSA2info((nmeaGPGSA *)pack, info);
break;
case GPGSV:
nmea_GPGSV2info((nmeaGPGSV *)pack, info);
break;
case GPRMC:
nmea_GPRMC2info((nmeaGPRMC *)pack, info);
break;
case GPVTG:
nmea_GPVTG2info((nmeaGPVTG *)pack, info);
break;
};
free(pack);
}
return nread;
}
int nmea_parser_push(nmeaPARSER *parser, const char *buff, int buff_sz)
{
int nparse, nparsed = 0;
do
{
if(buff_sz > parser->buff_size)
nparse = parser->buff_size; ///parser
else
nparse = buff_sz;
nparsed += nmea_parser_real_push( ///调用real_push
parser, buff, nparse);
buff_sz -= nparse;
} while(buff_sz);
return nparsed;
}
int nmea_parser_real_push(nmeaPARSER *parser, const char *buff, int buff_sz)
{
//nparsed已解析字符数,crc校验,sen_sz,ptype包头类型
int nparsed = 0, crc, sen_sz, ptype;
nmeaParserNODE *node = 0;
NMEA_ASSERT(parser && parser->buffer);
/* clear unuse buffer (for debug) */
/*
memset(
parser->buffer + parser->buff_use, 0,
parser->buff_size - parser->buff_use
);
*/
/* add */ //parser已用+要存>全部,即存储空间不够,则清理
if(parser->buff_use + buff_sz >= parser->buff_size)
nmea_parser_buff_clear(parser);
/空间够则拷贝到parser->buffer
memcpy(parser->buffer + parser->buff_use, buff, buff_sz);
parser->buff_use += buff_sz;
/* parse */
for(;;node = 0)
{
sen_sz = nmea_find_tail(
(const char *)parser->buffer + nparsed,
(int)parser->buff_use - nparsed, &crc);
if(!sen_sz)
{
if(nparsed)
memcpy(
parser->buffer,
parser->buffer + nparsed,
parser->buff_use -= nparsed);
break;
}
else if(crc >= 0)
{
ptype = nmea_pack_type(
(const char *)parser->buffer + nparsed + 1,
parser->buff_use - nparsed - 1);
if(0 == (node = malloc(sizeof(nmeaParserNODE)))) //根据node类型申请空间
goto mem_fail;
node->pack = 0;
switch(ptype)
{
case GPGGA:
if(0 == (node->pack = malloc(sizeof(nmeaGPGGA)))) /根据头类型申请包空间
goto mem_fail;
node->packType = GPGGA;
if(!nmea_parse_GPGGA(
(const char *)parser->buffer + nparsed,
sen_sz, (nmeaGPGGA *)node->pack))
{
free(node);
node = 0;
}
break;
case GPGSA:
if(0 == (node->pack = malloc(sizeof(nmeaGPGSA))))
goto mem_fail;
node->packType = GPGSA;
if(!nmea_parse_GPGSA(
(const char *)parser->buffer + nparsed,
sen_sz, (nmeaGPGSA *)node->pack))
{
free(node);
node = 0;
}
break;
case GPGSV:
if(0 == (node->pack = malloc(sizeof(nmeaGPGSV))))
goto mem_fail;
node->packType = GPGSV;
if(!nmea_parse_GPGSV(
(const char *)parser->buffer + nparsed,
sen_sz, (nmeaGPGSV *)node->pack))
{
free(node);
node = 0;
}
break;
case GPRMC:
if(0 == (node->pack = malloc(sizeof(nmeaGPRMC))))
goto mem_fail;
node->packType = GPRMC;
if(!nmea_parse_GPRMC(
(const char *)parser->buffer + nparsed,
sen_sz, (nmeaGPRMC *)node->pack))
{
free(node);
node = 0;
}
break;
case GPVTG:
if(0 == (node->pack = malloc(sizeof(nmeaGPVTG))))
goto mem_fail;
node->packType = GPVTG;
if(!nmea_parse_GPVTG(
(const char *)parser->buffer + nparsed,
sen_sz, (nmeaGPVTG *)node->pack))
{
free(node);
node = 0;
}
break;
default:
free(node);
node = 0;
break;
};
if(node)
{
if(parser->end_node)
((nmeaParserNODE *)parser->end_node)->next_node = node;
parser->end_node = node;
if(!parser->top_node)
parser->top_node = node;
node->next_node = 0;
}
}
nparsed += sen_sz;
}
return nparsed;
mem_fail:
if(node)
free(node);
nmea_error("Insufficient memory!");
return -1;
}
int nmea_parser_pop(nmeaPARSER *parser, void **pack_ptr)
{
int retval = GPNON;
nmeaParserNODE *node = (nmeaParserNODE *)parser->top_node;
NMEA_ASSERT(parser && parser->buffer);
if(node)
{
*pack_ptr = node->pack;
retval = node->packType;
parser->top_node = node->next_node;
if(!parser->top_node)
parser->end_node = 0;
free(node);
}
return retval;
}
3、parse.c中
int nmea_parse_GPRMC(const char *buff, int buff_sz, nmeaGPRMC *pack)
{
int nsen;
char time_buff[NMEA_TIMEPARSE_BUF];
NMEA_ASSERT(buff && pack);
memset(pack, 0, sizeof(nmeaGPRMC));
nmea_trace_buff(buff, buff_sz);
nsen = nmea_scanf(buff, buff_sz,
"$GPRMC,%s,%C,%f,%C,%f,%C,%f,%f,%2d%2d%2d,%f,%C,%C*",
&(time_buff[0]),
&(pack->status), &(pack->lat), &(pack->ns), &(pack->lon), &(pack->ew),
&(pack->speed), &(pack->direction),
&(pack->utc.day), &(pack->utc.mon), &(pack->utc.year),
&(pack->declination), &(pack->declin_ew), &(pack->mode));
if(nsen != 13 && nsen != 14)
{
nmea_error("GPRMC parse error!");
return 0;
}
if(0 != _nmea_parse_time(&time_buff[0], (int)strlen(&time_buff[0]), &(pack->utc)))
{
nmea_error("GPRMC time parse error!");
return 0;
}
if(pack->utc.year < 90)
pack->utc.year += 100;
pack->utc.mon -= 1;
return 1;
}
void nmea_GPRMC2info(nmeaGPRMC *pack, nmeaINFO *info)
{
NMEA_ASSERT(pack && info);
if('A' == pack->status)
{
if(NMEA_SIG_BAD == info->sig)
info->sig = NMEA_SIG_MID;
if(NMEA_FIX_BAD == info->fix)
info->fix = NMEA_FIX_2D;
}
else if('V' == pack->status)
{
info->sig = NMEA_SIG_BAD;
info->fix = NMEA_FIX_BAD;
}
info->utc = pack->utc;
info->lat = ((pack->ns == 'N')?pack->lat:-(pack->lat));
info->lon = ((pack->ew == 'E')?pack->lon:-(pack->lon));
info->speed = pack->speed * NMEA_TUD_KNOTS;
info->direction = pack->direction;
info->smask |= GPRMC;
}
4、tok.c中
int nmea_scanf(const char *buff, int buff_sz, const char *format, ...)
{
const char *beg_tok;
const char *end_buf = buff + buff_sz;
va_list arg_ptr;
int tok_type = NMEA_TOKS_COMPARE;
int width = 0;
const char *beg_fmt = 0;
int snum = 0, unum = 0;
int tok_count = 0;
void *parg_target;
va_start(arg_ptr, format);
for(; *format && buff < end_buf; ++format)
{
switch(tok_type)
{
case NMEA_TOKS_COMPARE:
if('%' == *format)
tok_type = NMEA_TOKS_PERCENT;
else if(*buff++ != *format)
goto fail;
break;
case NMEA_TOKS_PERCENT:
width = 0;
beg_fmt = format;
tok_type = NMEA_TOKS_WIDTH;
case NMEA_TOKS_WIDTH:
if(isdigit(*format))
break;
{
tok_type = NMEA_TOKS_TYPE;
if(format > beg_fmt)
width = nmea_atoi(beg_fmt, (int)(format - beg_fmt), 10);
}
case NMEA_TOKS_TYPE:
beg_tok = buff;
if(!width && ('c' == *format || 'C' == *format) && *buff != format[1])
width = 1;
if(width)
{
if(buff + width <= end_buf)
buff += width;
else
goto fail;
}
else
{
if(!format[1] || (0 == (buff = (char *)memchr(buff, format[1], end_buf - buff))))
buff = end_buf;
}
if(buff > end_buf)
goto fail;
tok_type = NMEA_TOKS_COMPARE;
tok_count++;
parg_target = 0; width = (int)(buff - beg_tok);
switch(*format)
{
case 'c':
case 'C':
parg_target = (void *)va_arg(arg_ptr, char *);
if(width && 0 != (parg_target))
*((char *)parg_target) = *beg_tok;
break;
case 's':
case 'S':
parg_target = (void *)va_arg(arg_ptr, char *);
if(width && 0 != (parg_target))
{
memcpy(parg_target, beg_tok, width);
((char *)parg_target)[width] = '\0';
}
break;
case 'f':
case 'g':
case 'G':
case 'e':
case 'E':
parg_target = (void *)va_arg(arg_ptr, double *);
if(width && 0 != (parg_target))
*((double *)parg_target) = nmea_atof(beg_tok, width);
break;
};
if(parg_target)
break;
if(0 == (parg_target = (void *)va_arg(arg_ptr, int *)))
break;
if(!width)
break;
switch(*format)
{
case 'd':
case 'i':
snum = nmea_atoi(beg_tok, width, 10);
memcpy(parg_target, &snum, sizeof(int));
break;
case 'u':
unum = nmea_atoi(beg_tok, width, 10);
memcpy(parg_target, &unum, sizeof(unsigned int));
break;
case 'x':
case 'X':
unum = nmea_atoi(beg_tok, width, 16);
memcpy(parg_target, &unum, sizeof(unsigned int));
break;
case 'o':
unum = nmea_atoi(beg_tok, width, 8);
memcpy(parg_target, &unum, sizeof(unsigned int));
break;
default:
goto fail;
};
break;
};
}
fail:
va_end(arg_ptr);
return tok_count;
}
四、嵌入式应用
1、修改context.h中的
原本 | 修改为 |
---|---|
#define NMEA_DEF_PARSEBUFF (1024) | #define NMEA_DEF_PARSEBUFF (512) |
#define NMEA_MIN_PARSEBUFF (256) | #define NMEA_MIN_PARSEBUFF (128) |
2、修改config.h中的
原本 | 修改为 |
---|---|
#define NMEA_CONVSTR_BUF (256) | #define NMEA_CONVSTR_BUF (128) |
#define NMEA_TIMEPARSE_BUF (256) | #define NMEA_TIMEPARSE_BUF (128) |
3、分析设置应用pack_type的流程
(1)、sentence.h中定义了nmeaPACKTYPE
enum nmeaPACKTYPE
{
GPNON = 0x0000, /**< Unknown packet type. */
GPGGA = 0x0001, /**< GGA - Essential fix data which provide 3D location and accuracy data. */
GPGSA = 0x0002, /**< GSA - GPS receiver operating mode, SVs used for navigation, and DOP values. */
GPGSV = 0x0004, /**< GSV - Number of SVs in view, PRN numbers, elevation, azimuth & SNR values. */
GPRMC = 0x0008, /**< RMC - Recommended Minimum Specific GPS/TRANSIT Data. */
GPVTG = 0x0010 /**< VTG - Actual track made good and speed over ground. */
};
(2)(parser.c)nmea_parser( )= =>(parser.c)nmea_parser_real_push()= =>(parse.c)nmea_pack_type()得到ptype,
real_push()中根据ptype申请数据空间,定义node的包类型packType
,而后解析。
nmea_parser()中将根据ptype类型nmea_GPRMC2info((nmeaGPRMC *)pack, info);
case GPRMC:
if(0 == (node->pack = malloc(sizeof(nmeaGPRMC))))
goto mem_fail;
node->packType = GPRMC;
if(!nmea_parse_GPRMC( (const char *)parser->buffer + nparsed,
sen_sz, (nmeaGPRMC *)node->pack))
4、修改parse.c中的nmea_pack_type( )
int nmea_pack_type(const char *buff, int buff_sz)
{
static const char *pheads[] = {
"GPGGA",
"GPGSA",
"GPGSV",
"GPRMC",
"GPVTG",
//正面为自己加的多模方式
"BDGGA", "BDGSA", "BDGSV", "BDRMC", "BDVTG",
"GNGGA", "GNGSA", "GNGSV", "GNRMC", "GNVTG",
};
NMEA_ASSERT(buff);
//多模加的
if(buff_sz < 5)
return GPNON;
else if((0 == memcmp(buff, pheads[0], 5)) || (0 == memcmp(buff, pheads[5], 5)) || (0 == memcmp(buff, pheads[10], 5)))
return GPGGA;
else if((0 == memcmp(buff, pheads[1], 5)) || (0 == memcmp(buff, pheads[6], 5)) || (0 == memcmp(buff, pheads[11], 5)))
return GPGSA;
else if((0 == memcmp(buff, pheads[2], 5)) || (0 == memcmp(buff, pheads[7], 5)) || (0 == memcmp(buff, pheads[12], 5)))
return GPGSV;
else if((0 == memcmp(buff, pheads[3], 5)) || (0 == memcmp(buff, pheads[8], 5)) || (0 == memcmp(buff, pheads[13], 5)))
return GPRMC;
else if((0 == memcmp(buff, pheads[4], 5)) || (0 == memcmp(buff, pheads[9], 5)) || (0 == memcmp(buff, pheads[14], 5)))
return GPVTG;
/
return GPNON;
}
4、修改parse.c中的nmea_parse_GPGGA()等函数以适配$BDRMC
,$GNRMC
将:
if(14 != nmea_scanf(buff, buff_sz,
"$GPGGA,%s,%f,%C,%f,%C,%d,%d,%f,%f,%C,%f,%C,%f,%d*",
修改为:
if(14 != nmea_scanf(&buff[3], buff_sz-3,
"GGA,%s,%f,%C,%f,%C,%d,%d,%f,%f,%C,%f,%C,%f,%d*",
5、开关项-----修改parse.c中的nmea_pack_type( )
注释掉相关包类型项,不返回类型即可。
6、nmealib处理无效数据
如果未定位或数据无效,nmealib仍会解析数据,判定处理过程(若自定义)在(parse.c)nmea_GPxxx2info( )
等函数中,结果在nmeaINFO中sig和fix中体现,其取值在info.h中定义。
sig (GPS quality indicator) | fix (Operating mode) |
---|---|
#define NMEA_SIG_BAD (0) | #define NMEA_FIX_BAD (1) |
#define NMEA_SIG_LOW (1) | #define NMEA_FIX_2D (2) |
#define NMEA_SIG_MID (2) | #define NMEA_FIX_3D (3) |
#define NMEA_SIG_HIGH (3) |
$GPGGA:<6> GPS状态:0=未定位,1=非差分定位,2=差分定位,6=正在估算
$GPGSA:<2> 定位类型,1=没有定位,2=2D定位,3=3D定位
$GPGSV:
$GPRMC:<2> 定位状态,A=有效定位,V=无效定位
$GPVTG:<5> 模式指示(仅NMEA0183 3.00版本输出,A=自主定位,D=差分,E=估算,N=数据无效)
$GPGLL:<7> 模式指示(仅NMEA0183 3.00版本输出,A=自主定位,D=差分,E=估算,N=数据无效)