实现最终的项目要求,依次从指定的TXT文件中读入有效的NMEA命令,实时进行封包,解析,条件筛选输出处理
main.c
#include
#include
#include
#include
#include"Type.h"
#include"Operation.h"
#include"Condition.h"
#include"Translate.h"
#include"Package.h"
#include"Analysis.h"
#include"Printout.h"
int main(void)
{
char avhemi;
float speed;
int svnum, sn;
printf("******************************\n");
printf("GPS Loading->NMEA-0183 Analyze\n");
printf("******************************\n");
avhemi = Condition_Locate();
speed = Condition_Speed();
svnum = Condition_Svnum();
sn = Condition_Sn();
printf("******************************\n");
printf("avc:%c,speed:%.3f,svnum=%d,sn=%d\n", avhemi, speed, svnum, sn);
printf("******************************\n");
Translate(avhemi, speed, svnum, sn);
return 0;
}
最为硬核的H文件
#ifndef _TRANSLATE_H_
#define _TRANSLATE_H_
#include
#include
#include
#include
#include"Type.h"
#include"Operation.h"
#include"Condition.h"
#include"Translate.h"
#include"Package.h"
#include"Analysis.h"
#include"Printout.h"
/******************************************************************************
* Function - Read and Analysis
*
* Purpose - 读取txt文件解析nmea有效命令
*
* Description -
*
* modification history
* ----------------------------------------
* v1.0 , 2018-12-20, LynxZhang written
* v2.0 , 2019-01-10, LynxZhang modific
* ----------------------------------------
******************************************************************************/
int Translate(char avhemi_, float speed_, int svnum_, int sn_)
{
FILE *fpr,*fpw;/*文件指针*/
char buf[256]="\0";
char tep[256]="\0";
char tmp[512]="\0";
static u8 dat[512]="\0";
int len=0;/*行字符个数*/
int sign=0;/*封包标志*/
int segm=0;/*命令断行标记*/
u8 *Buf;
Buf = (u8*)malloc(sizeof(u8) * 512);
if(Buf == NULL)
{
printf("指针Buf内存分配错误");
exit(1);
}
Nmea_msg *Res;
Res = (Nmea_msg *)malloc(sizeof(Nmea_msg));
if(Res == NULL)
{
printf("指针Res内存分配错误");
exit(1);
}
memset(Res, 0, sizeof(Nmea_msg));
char *head;/*NMEA命令头部地址*/
head = (char*)malloc(sizeof(char) * 256);
if(head == NULL)
{
printf("指针head内存分配错误");
exit(1);
}
memset(head, '\0', (sizeof(char) * 256));
char *tail;/*NMEA命令尾部地址*/
tail = (char*)malloc(sizeof(char) * 8);
if(tail == NULL)
{
printf("指针tail内存分配错误");
exit(1);
}
memset(tail, '\0', (sizeof(char) * 8));
if ((fpr=fopen("GPS_NMEA.txt", "r")) == NULL)/*开始读取文件*/
{
perror("Fail to read\n");
exit(1);
}
if ((fpw = fopen("Result.txt", "w")) == NULL)
{
perror("Fail to open\n");
exit(1);
}
while(fgets(buf,256,fpr) != NULL)/*读取直至文件结束,返回所有命令*/
{
if ((head = strstr(buf, "$"))||(segm == 1))/*NMEA命令起始判定//起始符*/
{
if (head != NULL)
{
strcpy(buf, head);
strcpy(tep,"\0");/*字符串清空处理*/
}
tail = strstr(buf, "*");
if(!tail)/*断句命令判定//结束符*/
{
segm = 1;
len = strlen(buf);
buf[len-1] = '\0';
strcat(tep, buf);
if(strlen(tep) >= 128)/*命令长度超常越界判定*/
{
segm = 0;
strcpy(tep, "\0");/*字符串清空处理*/
}
}
else
{
segm = 0;
*(tail + 3) = '\0';
strcat(tep, buf);
if(strnstr(tep, "$GNTXT", 6))
{
strcpy(tep, "\0");/*字符串清空处理*/
continue;
}
if(!NMEA_Checkout(tep))/*有效命令校验值判定*/
{
strcpy((char*)dat,"\0");/*字符串清空处理*/
strcpy(tmp,"\0");/*字符串清空处理*/
strcpy(tep,"\0");/*字符串清空处理*/
}
else
{
sign = Package(tep);/*检测封包标志*/
if(sign)
{
if(sign == 1)
{
strcat((char*)dat, tep);
strcat((char*)dat, "\n");
strcpy(tmp, "\0");/*字符串清空处理*/
strcpy(tep, "\0");/*字符串清空处理*/
}
else/*sign == 2*/
{
strcpy(tmp,"\0");
strcat(tmp, tep);
strcat(tmp,"\n");
Buf = (u8*)dat;
if(*Buf != '\0')
{
while (*Buf != '\0')
{
Buf = NMEA_GPZDA_Analysis(Res, Buf);
Buf = NMEA_GPGGA_Analysis(Res, Buf);
Buf = NMEA_GPGLL_Analysis(Res, Buf);
Buf = NMEA_GPVTG_Analysis(Res, Buf);
Buf = NMEA_GPGSA_Analysis(Res, Buf);
Buf = NMEA_GPGSV_Analysis(Res, Buf);
Buf = NMEA_GPRMC_Analysis(Res, Buf);
}
if((Res->utc.date != 0)&&(Res->utc.month != 0)&&(Res->utc.year != 0))/*日期信息有效*/
{
if(((Res->avhemi) == avhemi_) || (avhemi_ == 'C'))/*输入条件判断*/
{
if(((Res->speed) >= speed_) && ((Res->svnum) >= svnum_))
{
printout(Res,sn_,fpw);
}
}
}
memset(Res, 0, sizeof(Nmea_msg));
}
strcpy((char*)dat, "\0");
strcat((char*)dat, tmp);
}
}
else
{
strcpy((char*)dat,"\0");
strcpy(tmp, "\0");/*字符串清空处理*/
strcpy(tep, "\0");/*字符串清空处理*/
}
}
}
}
else
continue;
}
free(Buf);
Buf = NULL;
free(Res);
Res = NULL;
free(head);
head = NULL;
free(tail);
tail = NULL;
return 0;
}
#endif // _TRANSLATE_H_
NMEA-0183解析程序设计系列结束
本人也是根据国内的CSDN、博客园平台与国外的github进行学习,不过也从中发现大部分的不足之处:给出的代码实现思路不够明确,亦或是只实现对于指定单句NMEA命令和单类NMEA命令,或者是预先存入一定大小的NMEA命令于程序中的数组进行解析,实现效果都不够理想;
七篇系列文章中涉及的代码都由本人完成,其中对于NMEA中七类命令的解析实现思路来自学习其他前辈后自己编写改进而来,因此会与各类技术学习平台上他人的实现代码存在相似之处;
将所有代码合并入同一工程则可运行,编程实现周期为三周。