C语言解析GPS :GPGGA\GPRMC数据
C语言解析GPS :GPGGA\GPRMC数据
#ifndef _GN_GPSINFO_H__
#define _GN_GPSINFO_H__typedef int i4;
typedef unsigned int u4;
typedef short i2;
typedef unsigned short u2;
typedef signed char i1;
typedef unsigned char u1;
typedef float f4;
typedef double f8;#define ASCLL_DATA_$ '$'
#define ASCLL_DATA_GPGGA "$GPGGA"
#define ASCLL_DATA_GPRMC "$GPRMC"#define MAX_RCV_SIZE 1024*5
#define GPGGA_HEAD_LEN 0x06
#define CMP_SUCCESS 0x00
#define CMP_ERROR 0x01#define _switchState(a) pblkUartRcv->u1State = aenum
{RCV_STATE_IDIE = 0,RCV_STATE_START,RCV_GPGGA_HEAD,RCV_GPRMC_HEAD
};typedef struct
{u1 u1AscllName[10];u1 u1sizeof;u1 u1Head;
}GPS_ASCLLINFO;
typedef struct UartRcvTag
{u1 u1RcvBuff[MAX_RCV_SIZE];u1 u1State = 0;u1 u1DataLen;u1 u1Len;
}BlkUartRcv;//UTC时间信息
typedef struct
{u2 year; //年份u1 month; //月份u1 date; //日期u1 hour; //小时u1 min; //分钟u1 sec; //秒钟u1 ssec; //毫秒
}gps_utc_time;typedef struct
{gps_utc_time utc_time; // UTC时间f8 latitude_value; // 纬度u1 latitude; // 纬度半球f8 longtitude_value; // 经度u1 longitude; // 经度半球u1 gps_state; // GPS状态 0=未定位,1=非差分定位,2=差分定位,6=正在估算u1 sate_num; // 解算位置卫星数量f4 hdop; // HDOP水平精度因子f4 altitude; // 海拔高度
}GPGGA_INFO;typedef struct{gps_utc_time utc_time; // UTC时间u1 gps_state; // 定位状态f8 latitude_value; // 纬度u1 latitude; // 纬度半球f8 longtitude_value; // 经度u1 longtitude; // 经度半球f4 speed; // 地面速率f4 azimuth_angle; // 地面航向}GPRMC_INFO;int _Str2num(u1 *buf, u1*dx);void _GPRMC_Analysis(GPRMC_INFO *gps_rmc_info, u1 *buf);
void _GPGGA_Analysis(GPGGA_INFO *gps_gga_info, u1 *buf);#endif
// uart_test.cpp : 定义控制台应用程序的入口点。
//
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "gps_info.h"
#include "stdarg.h"
#include "math.h"GPS_ASCLLINFO Ascll_Info[2] = {ASCLL_DATA_GPGGA, 0x06, RCV_GPGGA_HEAD,ASCLL_DATA_GPRMC, 0x06, RCV_GPRMC_HEAD};
BlkUartRcv blkUartRcv;
GPGGA_INFO gga_info;
GPRMC_INFO gmc_info;//从buf里面得到第num个逗号所在的位置
//返回值:0~0xFE,代表逗号所在位置的偏移.
// 0xFF,代表不存在第num个逗号
u1 _Find_Pos(u1 *buf, u1 u1Num)
{u1 *p = buf;while (u1Num){if (*buf == '*' || *buf<' ' || *buf>'z')return 0xFF;//遇到'*'或者非法字符,则不存在第num个逗号if (*buf == ',')u1Num--;buf++;}return buf - p;
}//m^n函数
//返回值:m^n次方.
u4 _Pow(u1 m, u1 n)
{u4 result = 1;while (n--)result *= m;return result;
}
//str转换为数字,以','或者'*'结束
//buf:数字存储区
//dx:小数点位数,返回给调用函数
//返回值:转换后的数值
int _Str2num(u1 *buf, u1*dx)
{u1 *p = buf;u4 ires = 0, fres = 0;u1 ilen = 0, flen = 0, i;u1 mask = 0;double res;while (1) //得到整数和小数的长度{if (*p == '-'){ mask |= 0x02; p++; }//是负数if (*p == ',' || (*p == '*'))break;//遇到结束了if (*p == '.'){ mask |= 0x01; p++; }//遇到小数点了else if (*p>'9' || (*p<'0')) //有非法字符{ilen = 0;flen = 0;break;}if (mask & 0x01)flen++;else ilen++;p++;}if (mask & 0x02)buf++; //去掉负号for (i = 0; i<ilen; i++) //得到整数部分数据{ires += _Pow(10, ilen - 1 - i)*(buf[i] - '0');}if (flen>5)flen = 5; //最多取5位小数*dx = flen; //小数点位数for (i = 0; i<flen; i++) //得到小数部分数据{fres += _Pow(10, flen - 1 - i)*(buf[ilen + 1 + i] - '0');}res = ires*_Pow(10, flen) + fres;if (mask & 0x02)res = -res;return res;
}//分析GPRMC信息
//buf:接收到的GPS数据缓冲区首地址
void _GPRMC_Analysis(GPRMC_INFO *gps_rmc_info, u1 *buf)
{u1 *p1, dx;u1 posx;u4 temp;float rs;p1 = (u1*)strstr((const char *)buf, "$GPRMC"); // "$GPRMC"if (p1 == NULL){return;}posx = _Find_Pos(p1, 1); // 得到UTC时间if (posx != 0xFF){temp = _Str2num(p1 + posx, &dx) / _Pow(10, dx); // 得到UTC时间,去掉ms gps_rmc_info->utc_time.hour = temp / 10000;gps_rmc_info->utc_time.min = (temp / 100) % 100;gps_rmc_info->utc_time.sec = temp % 100;gps_rmc_info->utc_time.ssec = _Str2num(p1 + posx, &dx) % _Pow(10, dx);printf("GPS UTC 小时:%d 分钟:%d 秒:%d 毫秒:%d \n\r",gps_rmc_info->utc_time.hour,gps_rmc_info->utc_time.min,gps_rmc_info->utc_time.sec,gps_rmc_info->utc_time.ssec);}posx = _Find_Pos(p1, 2); // 得到定位状态if (posx != 0xFF){gps_rmc_info->gps_state = *(p1 + posx);printf("GPS卫星状态:%c \n\r", gps_rmc_info->gps_state);}posx = _Find_Pos(p1, 3); // 得到纬度值if (posx != 0xFF){temp = _Str2num(p1 + posx, &dx);gps_rmc_info->latitude_value = (f8)temp / (f8)_Pow(10, dx);printf("GPS纬度值:%.5f \n\r", gps_rmc_info->latitude_value);}posx = _Find_Pos(p1, 4); // 南纬还是北纬if (posx != 0xFF){gps_rmc_info->latitude = *(p1 + posx);printf("GPS纬度:%c \n\r", gps_rmc_info->latitude);}posx = _Find_Pos(p1, 5); // 得到经度值if (posx != 0xFF){temp = _Str2num(p1 + posx, &dx);gps_rmc_info->longtitude_value = (f8)temp / (f8)_Pow(10, dx);printf("GPS经度值:%.5f \n\r", gps_rmc_info->longtitude_value);}posx = _Find_Pos(p1, 6); // 东经还是西经if (posx != 0xFF){gps_rmc_info->longtitude = *(p1 + posx);printf("GPS经度:%c \n\r", gps_rmc_info->longtitude);}posx = _Find_Pos(p1, 7); // 速度if (posx != 0xFF){temp = _Str2num(p1 + posx, &dx);gps_rmc_info->speed = (f4)temp / (f4)_Pow(10, dx);printf("GPS速度值:%.3f \n\r", gps_rmc_info->speed);}posx = _Find_Pos(p1, 8); // 地面航向if (posx != 0xFF){temp = _Str2num(p1 + posx, &dx);gps_rmc_info->azimuth_angle = (f4)temp / (f4)_Pow(10, dx);printf("GPS速度值:%.3f \n\r", gps_rmc_info->azimuth_angle);}posx = _Find_Pos(p1, 9); //得到UTC日期if (posx != 0xFF){temp = _Str2num(p1 + posx, &dx); //得到UTC日期gps_rmc_info->utc_time.date = temp / 10000;gps_rmc_info->utc_time.month = (temp / 100) % 100;gps_rmc_info->utc_time.year = 2000 + temp % 100;printf("GPS UTC 年:%d 月:%d 日:%d \n\r",gps_rmc_info->utc_time.year,gps_rmc_info->utc_time.month,gps_rmc_info->utc_time.date);}
}//分析GPGGA信息
//buf:接收到的GPS数据缓冲区首地址
void _GPGGA_Analysis(GPGGA_INFO *gps_gga_info, u1 *buf)
{u1 *p1, dx;u1 posx;u4 temp;float rs;p1 = (u1*)strstr((const char *)buf, "$GPGGA"); // "$GPRMC"if ( p1 == NULL ){return;}posx = _Find_Pos(p1, 1); // 得到UTC时间if (posx != 0xFF){temp = _Str2num(p1 + posx, &dx) / _Pow(10, dx); // 得到UTC时间,去掉ms gps_gga_info->utc_time.hour = temp / 10000;gps_gga_info->utc_time.min = (temp / 100) % 100;gps_gga_info->utc_time.sec = temp % 100;gps_gga_info->utc_time.ssec = _Str2num(p1 + posx, &dx) % _Pow(10, dx);printf("GPS UTC 小时:%d 分钟:%d 秒:%d 毫秒:%d \n\r",gps_gga_info->utc_time.hour,gps_gga_info->utc_time.min,gps_gga_info->utc_time.sec,gps_gga_info->utc_time.ssec);}posx = _Find_Pos(p1, 2); // 得到纬度值if (posx != 0xFF){temp = _Str2num(p1 + posx, &dx);gps_gga_info->latitude_value = (f8)temp / (f8)_Pow(10, dx);printf("GPS纬度值:%.5f \n\r", gps_gga_info->latitude_value);}posx = _Find_Pos(p1, 3); // 南纬还是北纬if (posx != 0xFF){gps_gga_info->latitude = *(p1 + posx);printf("GPS纬度:%c \n\r", gps_gga_info->latitude);}posx = _Find_Pos(p1, 4); // 得到经度值if (posx != 0xFF){temp = _Str2num(p1 + posx, &dx);gps_gga_info->longtitude_value = (f8)temp / (f8)_Pow(10, dx);printf("GPS经度值:%.5f \n\r", gps_gga_info->longtitude_value);}posx = _Find_Pos(p1, 5); // 东经还是西经if (posx != 0xFF){gps_gga_info->longitude = *(p1 + posx);printf("GPS经度:%c \n\r", gps_gga_info->longitude);}posx = _Find_Pos(p1, 6); // GPS状态if (posx != 0xFF){temp = _Str2num(p1 + posx, &dx);gps_gga_info->gps_state = temp;printf("GPS状态值:%d \n\r", gps_gga_info->gps_state);}posx = _Find_Pos(p1, 7); // 卫星数量if (posx != 0xFF){temp = _Str2num(p1 + posx, &dx);gps_gga_info->sate_num = temp;printf("GPS卫星数量:%d \n\r", gps_gga_info->sate_num);}posx = _Find_Pos(p1, 8); // HDOP水平精度因子if (posx != 0xFF){gps_gga_info->hdop = (f4)temp / (f4)_Pow(10, dx);printf("HDOP水平精度因子:%f \n\r", gps_gga_info->hdop);}posx = _Find_Pos(p1, 9); // 海拔高度if (posx != 0xFF){temp = _Str2num(p1 + posx, &dx);gps_gga_info->altitude = (f4)temp / (f4)_Pow(10, dx);printf("海拔高度:%f \n\r", gps_gga_info->altitude);}
}void _ResetUartRcvBuff()
{memset(&blkUartRcv, 0, sizeof(BlkUartRcv));
}void GN_UartRcvGPSInfo(u1 u1Data)
{int check, sum, hour, min, sec;BlkUartRcv *pblkUartRcv = &blkUartRcv;u1 *pu1Buff = pblkUartRcv->u1RcvBuff;u1 u1size = 0;char u1utc[20];if ((u1Data == ASCLL_DATA_$) &&(pblkUartRcv->u1State == RCV_STATE_IDIE)){pblkUartRcv->u1State = RCV_STATE_START;}if (pblkUartRcv->u1DataLen >= MAX_RCV_SIZE){_ResetUartRcvBuff();}switch (pblkUartRcv->u1State){case RCV_STATE_START:pu1Buff[pblkUartRcv->u1DataLen++] = u1Data;if (u1Data == '\n'){for (u1size = 0; u1size < sizeof(Ascll_Info) / sizeof(GPS_ASCLLINFO); u1size++){if (CMP_SUCCESS == memcmp(&pu1Buff[0], Ascll_Info[u1size].u1AscllName, Ascll_Info[u1size].u1sizeof)){_switchState(Ascll_Info[u1size].u1Head);}}}break;case RCV_GPGGA_HEAD:printf("-----GPGGA------ \r\n");printf("GPGGA:%s \r\n",pu1Buff);_GPGGA_Analysis(&gga_info, pu1Buff); // GPGGA解析函数_ResetUartRcvBuff();break;case RCV_GPRMC_HEAD:printf("-----GPRMC------ \r\n");printf("GPRMC:%s \r\n", pu1Buff);_GPRMC_Analysis(&gmc_info, pu1Buff); // GPRMC解析函数_ResetUartRcvBuff();break;break;default:break;}
END:return;
}int main()
{// $GPGGA,105547.00,3959.99990484,N,11559.73608378,E,1,10,0.9,555.1075,M,-9.2296,M,,*7A\r\n// $GPRMC,105546.00,A,3959.99990614,N,11559.73608463,E,0.004,300.7,140622,5.7,W,A*22\r\nu1 nema_gga[] = "$GPRMC,105546.000,A,3959.99990614,N,11559.73608463,E,0.004,300.7,140622,5.7,W,A*22\r\n $GPGGA,105547.00,3959.99990484,N,11559.73608378,E,1,10,0.9,555.1075,M,-9.2296,M,,*7A\r\n";memset(&gmc_info, 0x00, sizeof(gmc_info));int i = sizeof(nema_gga);for (i = 0; i <= sizeof(nema_gga); i++){GN_UartRcvGPSInfo(nema_gga[i]);}getchar();return 0x00;
}
运行结果:
运行结果:
C语言解析GPS :GPGGA\GPRMC数据相关推荐
- C语言解析日志,存储数据到伯克利DB
编译命令 gcc -o dbwriter dbwriter.c -ldb dbwriter.c #include <assert.h> #include <stdlib.h> ...
- c语言中如何存储日志,C语言解析日志,存储数据到伯克利DB
#include #include#include#include#include #define DATABASE "demo.db" /*功能:解析日志提取数据(pv) 日志格 ...
- c语言mooc gps数据处理的数据_科研成果快报第102期:多GNSS观测数据质量分析软件...
多GNSS观测数据质量分析软件 Multi-GNSS Observables Quality Analysist 成果信息 软件名称:多GNSS观测数据质量分析软件[简称:MGOQA] V1.0 著作 ...
- 使用c语言解析gprmc数据
好的,我可以为您解释如何使用 C 语言解析 GPRMC 数据. GPRMC (Global Positioning System Receiver Monitoring Control) 是 GPS ...
- GPS数据格式 GPRMC 解析
nmealib是一个基于C语言的用于nmea协议的开源库. 在http://nmea.sourceforge.net/上下载的. 部分文件分析: 在头文件info.h中定义了NMEA解码需要的关键变量 ...
- GPS :NEMA数据解析
GPS 0183协议GGA.GLL.GSA.GSV.RMC.VTG解释 + 数据解析 每个时区跨15°经度.以0°经线为界向东向西各划出7.5°经度,作为0时区.即0时区的经度范围是7.5°W--7. ...
- GPS的NMEA数据解析
NMEA是一套定义接收机输出的标准信息,有几种不同的格式,每种都是独立相关的ASCII格式,逗点隔开数据流,数据流长度从30-100字符不等,通常以每秒间隔选择输出,最常用的格式为"GGA& ...
- linux nmea解析程序,GPS的NMEA数据解析
NMEA是一套定义接收机输出的标准信息,有几种不同的格式,每种都是独立相关的ASCII格式,逗点隔开数据流,数据流长度从30-100字符不 等,通常以每秒间隔选择输出,最常用的格式为"GGA ...
- C语言实现解析gps坐标(在一串字符串中找到北纬和东经的值)
C语言实现解析gps坐标 一.要求 二.实现代码 1.方法一: 2.方法二 一.要求 解析gps坐标 Gps一帧数据,如下: const char input[1024] ="$GNGGA, ...
最新文章
- 如何恢复,迁移,添加, 删除 Voting Disks
- Vim的行号、语法显示等设置(.vimrc文件的配置)以及乱码解决
- open-v-p-n原理解读及实例服务部署
- 寒假与春节终归,新学期和新任务又至
- ReentrantReadWriteLock可重入读写锁分析
- JDBC连接 Mysql数据库
- Spring学习笔记-构造和Set方法注入Bean及集合和null值的注入
- 【Flink】Flink Kafka 消费卡死 消费组卡死 topic无写入 实际有数据 topic正常
- 【报告分享】中美人工智能之比较分析报告.pdf(附下载链接)
- maven 下载不到jar包时候,更改阿里源
- html是什么意思 它是一种什么样的语言,HTML 是什么?
- licecap图片区域问题
- 陪诊系统app开发,一个应用可切换不同身份
- 为chrome浏览器单独设置代理服务器
- 【其他】手机bilibili的视频文件在哪个目录
- 做实景三维项目后的一些感想
- @Transactional(propagation)
- 前端学习13:HTML响应式设计、计算机代码、语义元素
- 洛谷1710 地铁涨价
- 第一次接python私活,就被骗了···表弟让我再也别接私活了
热门文章
- PAT 乙级 1006 换个格式输出整数
- 浙大PAT1028人口普查 C++ 测试点格式错误 问题所在
- 《Unity开发实战》——3.4节创建高光纹理贴图
- ASP.NET Boilerplate v5升级到Abp vNext的改动
- 阿里天池竞赛 A股上市公司营收预测 使用LSTM模型做时序预测
- 善领电子狗 计算机无法识别,[已解决]如何修复USB设备无法轻松识别
- ThoughtWorks(中国)程序员读书雷达
- 什么是IT审计(转)
- Uncaught SyntaxError: await is only valid in async functions...,以及async的就近原则
- Mac OS X下开发软件的安装与配置(持续更新ing)