程序员tim 提供了一个非常完善的nmea解码库,直接使用该解码库,可以避免重复发明轮子的工作。在野火提供的gps模块资料的“nmea0183解码库源码”文件夹中也包含了该解码库的源码,野火提供的stm32程序就是使用该库来解码nmea语句的。
该解码库目前最新为0.5.3版本,它使用纯c语言编写,支持windows、wince 、unix平台,支持解析gpgga,gpgsa,gpgsv,gprmc,gpvtg这五种语句(这五种语句已经提供足够多的gps信息),解析得的gps数据信息以结构体存储,附加了地理学相关功能,可支持导航等数据工作,除了解析nmea语句,它还可以根据随机数产生nmea语句,方便模拟。
0.nmealib简介
nmealib是一个基于c语言的用于nmea协议的开源库。虽然nmea体积小巧,但是却具备了不少功能。
分析nmea语句并把结果保存在合适的c语言结构体中。
除了解析nmea语句之外,还可以产生nmea语句。
支持多种nmea语句,包括gpgga, gpgsa, gpgsv, gprmc, gpvtg。
解析算法层次严谨。
附加地理学相关功能,可支持导航等数据工作。
1.目录介绍
nmealib的目录还是非常清晰的,下面简单介绍一下。
include\nmealib文件夹中存在nmealib相关的头文件
src文件夹存放nmealib相关源文件,该文件夹中的内容和include\nmealib文件夹相对应
samples文件夹存放若干例子,一些简单易懂的例子。
2.示例代码
[cpp]view plaincopy
#include
#include
#include
intmain()
{
//被测试的gps模块输出数据,仅有gprmc格式
chargps_str[]=$gprmc,013257.00,a,3129.51829,n,12022.10562,e,0.093,,270813,,,a*7a\r\n;
nmeainfoinfo;//nmea协议解析结果结构体
nmeaparserparser;//nmea协议解析载体
nmea_zero_info(&info);//填入默认的解析结果
nmea_parser_init(&parser);//为解析载体分配内存空间
//调用函数完成gps信息解析,最终结果保留于info数组中
if((nmea_parse(&parser,gps_str,(int)strlen(gps_str),&info))>0)
{
printf(longitude%.5f\r\n,info.lon);
printf(latitude%.5f\r\n,info.lat);
printf(speed%.2f\r\n,info.speed);
}
nmea_parser_destroy(&parser);//释放解析载体的内存空间
return0;
}
图1 程序输出结果
利用nmealib解析gps模块的输出结果大致可以分为三步,第一步定义和初始化gps信息结构体和解析载体结构体,第二步调用nmea_parse函数完成解析工作,第三步释放解析载体所占用的内存空间。如果仔细查看nmea_parser_init部分的代码,便会发现函数中使用了c标准库的malloc函数,该函数会在ram中的heap空间开辟一个空间,这就需要使用完该载体之后立刻释放,所以nmea_parser_init和nmea_parser_destroy需要成对出现。
[cpp]view plaincopy
typedefstruct_nmeainfo
{
intsmask;/**
nmeatimeutc;/**
intsig;/**
intfix;/**
doublepdop;/**
doublehdop;/**
doublevdop;/**
doublelat;/**
doublelon;/**
doubleelv;/**
doublespeed;/**
doubledirection;/**
doubledeclination;/**
nmeasatinfosatinfo;/**linker,cstack和heap的大小设置如下图所示,此时heap的大小仅有512个字节,而解析载体却需要1024个字节,那么分配内存时势必会产生问题,而工程的编译却不会有任何问题。
图2 不合适的heap大小设置
[cpp]view plaincopy
if(0==(parser->buffer=malloc(buff_size)))
nmea_error(insufficientmemory!);//此时会发生内存分配错误
else
{
parser->buff_size=buff_size;
resv=1;
}
在这种情况下可以适当减少缓冲区的大小,例如修改如下:
#define nmea_def_parsebuff (256)
#define nmea_min_parsebuff (128)
同时可以把heap空间大小的调整一下。
图3 合适的heap大小设置
当然缓冲区的大小也是视情况而定,若gps模块仅输出gprmc语句,那么256字节的缓冲区已经足够了。但是如果gps模块输出gpgga, gpgsa, gpgsv, gprmc, gpvtg等多种数据,那么256字节的缓冲区也有可能不够使用。
3.2 注意nmeainfo结构体大小
nmeainfo结构体左右360字节,若该结构体类型的变量势必会占用较多的cstack(全局变量的情况除外),在嵌入式编程中像nmeainfo类型的变量也可算的上是中型“人物”了。所以在调试的过程中可以打开ide的stack查看功能(进入debug模式,view->stack),观察当前函数的cstack使用情况,尤其要注意cstack越界的情况。
图4 查看cstack空间占用情况
从上图可以看出,cstack的大小为2048字节(2k),此时被占用752字节,占用率为36%,完全在可以接受的范围内。
4.总结
nmealib的使用可以缩短gps的开发周期,这里只是简单的举例了nmealib的基本功能,更多的功能可以查看samples文件夹中的例子,并在实践中不断熟悉提高。
区块链分层“Layering“解析
教你如何选择A/D芯片
腾讯医疗:希望用互联网和科技让医疗资源实现价值最大化
光伏电站监控解决方案|逆变器|能耗监测|能量管理系统
致我的"芯上人"
nmealib的使用可以缩短GPS的开发周期
北斗星通推出国内首颗55纳米北斗芯片
嵌入式闪存所带来的变化都有哪些
我国歼-20战机WS-15发动机有多厉害?可抗衡美军F-22
2020一季度PC市场份额 联想惠普戴尔排名前三
南京宁瑞计量冲压钣金件汽车钣金件冲压折弯件三维激光扫描检测仪厂家提供三维扫描
升腾910和英伟达A100的区别
基于ClockMatrix系列的PHY参考设计
宝马看好MEB电子模块化架构
什么是数字农业建设项目,它有哪些作用
如何在Java中加密和解密zip文件
安谋携手四川打造芯片设计研究院
PCB板制作过程中怎么会出现甩铜现象
天音控股拟定增募资25亿元 强化智能手机等业务布局
LED工艺技术介绍