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数据相关推荐

  1. C语言解析日志,存储数据到伯克利DB

    编译命令 gcc -o dbwriter dbwriter.c -ldb dbwriter.c #include <assert.h> #include <stdlib.h> ...

  2. c语言中如何存储日志,C语言解析日志,存储数据到伯克利DB

    #include #include#include#include#include #define DATABASE "demo.db" /*功能:解析日志提取数据(pv) 日志格 ...

  3. c语言mooc gps数据处理的数据_科研成果快报第102期:多GNSS观测数据质量分析软件...

    多GNSS观测数据质量分析软件 Multi-GNSS Observables Quality Analysist 成果信息 软件名称:多GNSS观测数据质量分析软件[简称:MGOQA] V1.0 著作 ...

  4. 使用c语言解析gprmc数据

    好的,我可以为您解释如何使用 C 语言解析 GPRMC 数据. GPRMC (Global Positioning System Receiver Monitoring Control) 是 GPS ...

  5. GPS数据格式 GPRMC 解析

    nmealib是一个基于C语言的用于nmea协议的开源库. 在http://nmea.sourceforge.net/上下载的. 部分文件分析: 在头文件info.h中定义了NMEA解码需要的关键变量 ...

  6. GPS :NEMA数据解析

    GPS 0183协议GGA.GLL.GSA.GSV.RMC.VTG解释 + 数据解析 每个时区跨15°经度.以0°经线为界向东向西各划出7.5°经度,作为0时区.即0时区的经度范围是7.5°W--7. ...

  7. GPS的NMEA数据解析

    NMEA是一套定义接收机输出的标准信息,有几种不同的格式,每种都是独立相关的ASCII格式,逗点隔开数据流,数据流长度从30-100字符不等,通常以每秒间隔选择输出,最常用的格式为"GGA& ...

  8. linux nmea解析程序,GPS的NMEA数据解析

    NMEA是一套定义接收机输出的标准信息,有几种不同的格式,每种都是独立相关的ASCII格式,逗点隔开数据流,数据流长度从30-100字符不 等,通常以每秒间隔选择输出,最常用的格式为"GGA ...

  9. C语言实现解析gps坐标(在一串字符串中找到北纬和东经的值)

    C语言实现解析gps坐标 一.要求 二.实现代码 1.方法一: 2.方法二 一.要求 解析gps坐标 Gps一帧数据,如下: const char input[1024] ="$GNGGA, ...

最新文章

  1. 如何恢复,迁移,添加, 删除 Voting Disks
  2. Vim的行号、语法显示等设置(.vimrc文件的配置)以及乱码解决
  3. open-v-p-n原理解读及实例服务部署
  4. 寒假与春节终归,新学期和新任务又至
  5. ReentrantReadWriteLock可重入读写锁分析
  6. JDBC连接 Mysql数据库
  7. Spring学习笔记-构造和Set方法注入Bean及集合和null值的注入
  8. 【Flink】Flink Kafka 消费卡死 消费组卡死 topic无写入 实际有数据 topic正常
  9. 【报告分享】中美人工智能之比较分析报告.pdf(附下载链接)
  10. maven 下载不到jar包时候,更改阿里源
  11. html是什么意思 它是一种什么样的语言,HTML 是什么?
  12. licecap图片区域问题
  13. 陪诊系统app开发,一个应用可切换不同身份
  14. 为chrome浏览器单独设置代理服务器
  15. 【其他】手机bilibili的视频文件在哪个目录
  16. 做实景三维项目后的一些感想
  17. @Transactional(propagation)
  18. 前端学习13:HTML响应式设计、计算机代码、语义元素
  19. 洛谷1710 地铁涨价
  20. 第一次接python私活,就被骗了···表弟让我再也别接私活了

热门文章

  1. PAT 乙级 1006 换个格式输出整数
  2. 浙大PAT1028人口普查 C++ 测试点格式错误 问题所在
  3. 《Unity开发实战》——3.4节创建高光纹理贴图
  4. ASP.NET Boilerplate v5升级到Abp vNext的改动
  5. 阿里天池竞赛 A股上市公司营收预测 使用LSTM模型做时序预测
  6. 善领电子狗 计算机无法识别,[已解决]如何修复USB设备无法轻松识别
  7. ThoughtWorks(中国)程序员读书雷达
  8. 什么是IT审计(转)
  9. Uncaught SyntaxError: await is only valid in async functions...,以及async的就近原则
  10. Mac OS X下开发软件的安装与配置(持续更新ing)