1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/boo0ood-NMEA_GPS_parse

Присоединиться к Gitlife
Откройте для себя и примите участие в публичных проектах с открытым исходным кодом с участием более 10 миллионов разработчиков. Приватные репозитории также полностью бесплатны :)
Присоединиться бесплатно
Клонировать/Скачать
gps.c 15 КБ
Копировать Редактировать Web IDE Исходные данные Просмотреть построчно История
iE-zhi Отправлено 17.09.2024 17:52 51cc114
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543
//
// Created by ihz on 2020/6/4.
//
#include "gps.h"
static GPS gps_all;
static char gps_src_backup[1024];
// 数据分割,可以分割两个连续的分隔符
static char* strsplit(char** stringp, const char* delim)
{
char* start = *stringp;
char* p;
p = (start != NULL) ? strpbrk(start, delim) : NULL;
if (p == NULL)
{
*stringp = NULL;
}
else
{
*p = '\0';
*stringp = p + 1;
}
return start;
}
// 统计字符串在另一个字符串中出现的次数
static int strstr_cnt(char *str, char *substr)
{
char *srcStr = str;
int count = 0;
do
{
srcStr = strstr(srcStr, substr);
if(srcStr != NULL)
{
count++;
srcStr = srcStr + strlen(substr);
}
else
{
break;
}
}while (*srcStr != '\0');
return count;
}
#if ENABLE_GGA
// GGA数据解析
static GGA gga_data_parse(char *gga_data)
{
GGA gga;
unsigned char times = 0;
char *p;
char end[16];
p = strsplit(&gga_data, ",");
while (p)
{
switch (times)
{
case 1: // UTC
strcpy(gga.utc, p);
break;
case 2: // lat
gga.lat = strtod(p, NULL);
break;
case 3: // lat dir
gga.lat_dir = p[0];
break;
case 4: // lon
gga.lon = strtod(p, NULL);
break;
case 5: // lon dir
gga.lon_dir = p[0];
break;
case 6: // quality
gga.quality = (unsigned char)strtol(p, NULL, 10);
break;
case 7: // sats
gga.sats = (unsigned char)strtol(p, NULL, 10);
break;
case 8: // hdop
gga.hdop = strtod(p, NULL);;
break;
case 9: // alt
gga.alt = strtod(p, NULL);
break;
case 11: // undulation
gga.undulation = strtod(p, NULL);
break;
case 13: // age
gga.age = (unsigned char)strtol(p, NULL, 10);
break;
case 14: // stn_ID
strncpy(end, p, strlen(p)-3);
end[strlen(p)-3] = '\0';
gga.stn_ID = (unsigned short )strtol(end, NULL, 10);
break;
default:
break;
}
p = strsplit(&gga_data, ",");
times++;
}
return gga;
}
#endif
#if ENABLE_GLL
// GLL数据解析
static GLL gll_data_parse(char *gll_data)
{
GLL gll;
unsigned char times = 0;
char *p;
char *s = gll_data;
p = strsplit(&s, ",");
while (p)
{
switch (times)
{
case 1: // lat
gll.lat = strtod(p, NULL);
break;
case 2: // lat dir
gll.lat_dir = p[0];
break;
case 3: // lon
gll.lon = strtod(p, NULL);
break;
case 4: // lon dir
gll.lon_dir = p[0];
break;
case 5: // lon dir
strcpy(gll.utc, p);
break;
case 6: // data status
gll.data_status = p[0];
break;
default:
break;
}
p = strsplit(&s, ",");
times++;
}
return gll;
}
#endif
#if ENABLE_GSA
// 得到GSA数据中的信道信息
static void get_prn_data(char *gps_data, GSA_PRN *gsa_prn)
{
unsigned char times = 0;
unsigned char i;
unsigned char sentences_index = 0; // 累计找到gsa字段的个数
char *p;
char gsa_data_buffer[128];
char *s = gsa_data_buffer;
char *sentences;
int gsa_count;
// 统计GSA字段的个数
gsa_count = strstr_cnt(gps_data, PRE_GSA);
(void)memset(gsa_prn, 0, sizeof(GSA_PRN) * MAX_GSA_CHANNELS);
sentences = strtok(gps_data, "\r\n");
while (sentences)
{
if (strstr(sentences, PRE_GSA))
{
sentences_index++;
s = gsa_data_buffer;
(void)memcpy(s, sentences, strlen(sentences));
p = strsplit(&s, ",");
while (p)
{
if (times == 2)
{
for (i=0; i<12; i++)
{
p = strsplit(&s, ",");
(gsa_prn+i+(sentences_index-1)*12)->total = (unsigned char)gsa_count * 12;
(gsa_prn+i+(sentences_index-1)*12)->prn_ID = i + (sentences_index - 1) * 12;
(gsa_prn+i+(sentences_index-1)*12)->prn = (unsigned char)strtol(p, NULL, 10);
}
}
p = strsplit(&s, ",");
times++;
}
times = 0;
}
sentences = strtok(NULL, "\r\n");
}
}
// GSA数据解析
static GSA gsa_data_parse(char *gsa_data, char *gpsdata)
{
GSA gsa;
unsigned char times = 0;
char *p;
char end[16];
char *s = gsa_data;
char *alldata = gpsdata;
p = strsplit(&s, ",");
while (p)
{
switch (times)
{
case 1: // mode_MA
gsa.mode_MA = p[0];
break;
case 2: // mode_123
gsa.mode_123 = p[0];
break;
case 3: // prn
get_prn_data(alldata, gsa.gsa_prn);
break;
case 15: // pdop
gsa.pdop = strtod(p, NULL);
break;
case 16: // hdop
gsa.hdop = strtod(p, NULL);
break;
case 17: // vdop
strncpy(end, p, strlen(p)-3);
end[strlen(p)-3] = '\0';
gsa.vdop = strtod(end, NULL);
default:
break;
}
p = strsplit(&s, ",");
times++;
}
return gsa;
}
#endif
#if ENABLE_RMC
// RMC数据解析
static RMC rmc_data_parse(char *rmc_data)
{
RMC rmc;
unsigned char times = 0;
char *p;
char *s = rmc_data;
p = strsplit(&s, ",");
while (p)
{
switch (times)
{
case 1: // UTC
strcpy(rmc.utc, p);
break;
case 2: // pos status
rmc.pos_status = p[0];
break;
case 3: // lat
rmc.lat = strtod(p, NULL);
break;
case 4: // lat dir
rmc.lat_dir = p[0];
break;
case 5: // lon
rmc.lon = strtod(p, NULL);
break;
case 6: // lon dir
rmc.lon_dir = p[0];
break;
case 7: // speen Kn
rmc.speed_Kn = strtod(p, NULL);
break;
case 8: // track true
rmc.track_true = strtod(p, NULL);
break;
case 9: // date
strcpy(rmc.date, p);
break;
case 10: // mag var
rmc.mag_var = strtod(p, NULL);
break;
case 11: // var dir
rmc.var_dir = p[0];
break;
case 12: // mode ind
rmc.mode_ind = p[0];
break;
default:
break;
}
p = strsplit(&s, ",");
times++;
}
return rmc;
}
#endif
#if ENABLE_VTG
// VTG数据解析
static VTG vtg_data_parse(char *vtg_data)
{
VTG vtg;
unsigned char times = 0;
char *p;
char *s = vtg_data;
p = strsplit(&s, ",");
while (p)
{
switch (times)
{
case 1: // track true
vtg.track_true = strtod(p, NULL);
break;
case 3: // track mag
vtg.track_mag = strtod(p, NULL);
break;
case 5: // speed Kn
vtg.speed_Kn = strtod(p, NULL);
break;
case 7: // speed Km
vtg.speed_Km = strtod(p, NULL);
break;
default:
break;
}
p = strsplit(&s, ",");
times++;
}
return vtg;
}
#endif
#if ENABLE_GSV
/*
* function: 获取GSV字段中的GPS信息
* gps_data: 最原始的GPS字符串
* stas: 卫星数量
* prefix: GSV信息字段前缀
* sats_info: 存放卫星信息
*/
static void get_sats_info(char *gps_data, unsigned char sats, char *prefix, SAT_INFO *sats_info)
{
unsigned char times = 0;
unsigned char msgs = 0;
unsigned char msg = 0;
unsigned char for_times;
unsigned char i;
char *p;
char gsv_data_buffer[128];
char *s = gsv_data_buffer;
char *sentences;
(void)memset(sats_info, 0, sizeof(SAT_INFO) * (sats+1));
sentences = strtok(gps_data, "\r\n");
while (sentences)
{
if (strstr(sentences, prefix))
{
s = gsv_data_buffer;
(void)memcpy(s, sentences, strlen(sentences));
p = strsplit(&s, ",");
while (p)
{
switch (times)
{
case 1: // msgs
msgs = (unsigned char) strtol(p, NULL, 10);
break;
case 2: // msg
msg = (unsigned char) strtol(p, NULL, 10);
break;
case 3: // sat info
for_times = (msgs == msg) ? ((sats % 4) ? sats % 4 : 4) : 4;
for (i = 0; i < for_times; i++)
{
p = strsplit(&s, ",");
(sats_info+(msg-1)*4+i)->prn = (unsigned char) strtol(p, NULL, 10);
p = strsplit(&s, ",");
(sats_info+(msg-1)*4+i)->elev = (unsigned char) strtol(p, NULL, 10);
p = strsplit(&s, ",");
(sats_info+(msg-1)*4+i)->azimuth = (unsigned short) strtol(p, NULL, 10);
p = strsplit(&s, ",");
(sats_info+(msg-1)*4+i)->SNR = (unsigned char) strtol(p, NULL, 10);
}
break;
default:
break;
}
p = strsplit(&s, ",");
times++;
}
times = 0;
}
sentences = strtok(NULL, "\r\n");
}
}
// GSV数据解析
static GSV gsv_data_parse(char *gsv_data, char *gps_data, char *prefix)
{
GSV gsv;
unsigned char times = 0;
char *p;
char *s = gsv_data;
char *src_data = gps_data;
p = strsplit(&s, ",");
while (p)
{
switch (times)
{
case 1: // msgs
gsv.msgs = (unsigned char)strtol(p, NULL, 10);
break;
case 2: // msg
gsv.msg = (unsigned char)strtol(p, NULL, 10);
break;
case 3: // sats
gsv.sats = (unsigned char)strtol(p, NULL, 10);
get_sats_info(src_data, gsv.sats, prefix, gsv.sat_info);
break;
default:
break;
}
p = strsplit(&s, ",");
times++;
}
return gsv;
}
#endif
#if ENABLE_UTC
// UTC数据解析
static UTC utc_parse(char *date, char *time)
{
UTC utc_data;
unsigned int date_int;
double time_float;
date_int = (unsigned int)strtol(date, NULL, 10);
utc_data.DD = date_int / 10000;
utc_data.MM = date_int % 10000 / 100;
utc_data.YY = date_int % 100;
time_float = strtod(time, NULL);
utc_data.hh = (unsigned int)time_float / 10000;
utc_data.mm = (unsigned int)time_float % 10000 / 100;
utc_data.ss = (unsigned int)time_float % 100;
utc_data.ds = (unsigned short)(time_float - (unsigned int)time_float);
return utc_data;
}
#endif
// 解析全部的GPS数据
GPS gps_data_parse(const char* gps_src, const unsigned short gps_src_len)
{
// GGA数据解析
#if ENABLE_GGA
(void)memset(gps_all.gps_buffer_data, 0u, sizeof(gps_all.gps_buffer_data));
(void)memcpy(gps_all.gps_buffer_data, gps_src, gps_src_len);
GGA default_gga_data = {"\0",0.0,'N',0.0,'S',0,0,0,0,0,0,0};
gps_all.gga_data = strstr(gps_src, PRE_GGA) ? gga_data_parse(strtok(strstr(gps_all.gps_buffer_data, PRE_GGA), "\r\n")) : default_gga_data;
#endif
// GLL数据解析
#if ENABLE_GLL
(void)memset(gps_all.gps_buffer_data, 0u, sizeof(gps_all.gps_buffer_data));
(void)memcpy(gps_all.gps_buffer_data, gps_src, gps_src_len);
GLL default_gll_data = {0.0,'\0',0.0,'\0',"\0",'\0'};
gps_all.gll_data = strstr(gps_src, PRE_GLL) ? gll_data_parse(strtok(strstr(gps_all.gps_buffer_data, PRE_GLL), "\r\n")) : default_gll_data;
#endif
// GSA数据解析
#if ENABLE_GSA
GSA_PRN default_gsa_prn_data = {0,0,0};
GSA default_gsa_data = {'\0','\0',0.0,0.0,0.0, default_gsa_prn_data};
(void)memcpy(gps_src_backup, gps_src, gps_src_len);
gps_all.gsa_data = strstr(gps_src, PRE_GSA) ? gsa_data_parse(strtok(strstr(gps_all.gps_buffer_data, PRE_GSA), "\r\n"), gps_src_backup) : default_gsa_data;
#endif
// RMC数据解析
#if ENABLE_RMC
RMC default_rmc_data = {"\0",'\0',0.0,'\0',0.0,'\0',0.0,0.0,"\0",0.0,'\0','\0'};
(void)memset(gps_all.gps_buffer_data, 0u, sizeof(gps_all.gps_buffer_data));
(void)memcpy(gps_all.gps_buffer_data, gps_src, gps_src_len);
gps_all.rmc_data = strstr(gps_src, PRE_RMC) ? rmc_data_parse(strtok(strstr(gps_all.gps_buffer_data, PRE_RMC), "\r\n")) : default_rmc_data;
#endif
// VTG数据解析
#if ENABLE_VTG
VTG default_vtg_data = {0.0,0.0,0.0,0.0};
(void)memset(gps_all.gps_buffer_data, 0u, sizeof(gps_all.gps_buffer_data));
(void)memcpy(gps_all.gps_buffer_data, gps_src, gps_src_len);
gps_all.vtg_data = strstr(gps_src, PRE_VTG) ? vtg_data_parse(strtok(strstr(gps_all.gps_buffer_data, PRE_VTG), "\r\n")) : default_vtg_data;
#endif
// GSV数据解析
#if ENABLE_GSV
SAT_INFO default_sat_info_data = {0,0,0,0};
GSV default_gsv_data = {0, 0, 0, default_sat_info_data};
(void)memset(gps_all.gps_buffer_data, 0u, sizeof(gps_all.gps_buffer_data));
(void)memcpy(gps_all.gps_buffer_data, gps_src, gps_src_len);
(void)memcpy(gps_src_backup, gps_src, gps_src_len);
// GPGSV数据段解析
gps_all.gpgsv_data = strstr(gps_src, PRE_GPGSV) ? gsv_data_parse(strtok(strstr(gps_all.gps_buffer_data, PRE_GPGSV), "\r\n"), gps_src_backup, PRE_GPGSV) : default_gsv_data;
// GNGSV数据段解析
(void)memset(gps_all.gps_buffer_data, 0u, sizeof(gps_all.gps_buffer_data));
(void)memcpy(gps_all.gps_buffer_data, gps_src, gps_src_len);
(void)memcpy(gps_src_backup, gps_src, gps_src_len);
gps_all.gngsv_data = strstr(gps_src, PRE_GNGSV) ? gsv_data_parse(strtok(strstr(gps_all.gps_buffer_data, PRE_GNGSV), "\r\n"), gps_src_backup, PRE_GNGSV) : default_gsv_data;
// GLGSV数据段解析
(void)memset(gps_all.gps_buffer_data, 0u, sizeof(gps_all.gps_buffer_data));
(void)memcpy(gps_all.gps_buffer_data, gps_src, gps_src_len);
(void)memcpy(gps_src_backup, gps_src, gps_src_len);
gps_all.glgsv_data = strstr(gps_src, PRE_GLGSV) ? gsv_data_parse(strtok(strstr(gps_all.gps_buffer_data, PRE_GLGSV), "\r\n"), gps_src_backup, PRE_GLGSV) : default_gsv_data;
#endif
// UTC数据解析,UTC数据取自RMC段数据
#if ENABLE_UTC && ENABLE_RMC
gps_all.utc = utc_parse(gps_all.rmc_data.date, gps_all.rmc_data.utc);
#endif
return gps_all;
}

Опубликовать ( 0 )

Вы можете оставить комментарий после Вход в систему

1
https://api.gitlife.ru/oschina-mirror/boo0ood-NMEA_GPS_parse.git
git@api.gitlife.ru:oschina-mirror/boo0ood-NMEA_GPS_parse.git
oschina-mirror
boo0ood-NMEA_GPS_parse
boo0ood-NMEA_GPS_parse
master