NMEA报文解析程序(c语言)-解析报文
程序员文章站
2022-03-06 18:57:52
...
开发工具:DEV
NMEA协议基础知识可参见:GPS理论知识NMEA 0813协议
为完成课程设计而参照网上例子,按照课程要求修改而来
1、在搜集资料过程中发现网上很多都不完整,而且有的会有很多小错误,无法有效运行,自己调试后做了一些修改,能成功运行。
2、因为是上个学期的作业,有些细节不太记得了,但是代码里有修改的地方我都有注释,大家可以参照这些代码段根据自己的需求构建程序。
3、完整工程可以私信我,留下邮箱,看到就会第一时间发送。 加上网盘链接吧,里面还附了DEV(免安装的)
baidu链接
提取码:axpl
4、有错误的地方也希望大家能够指正。
系列二:解析报文
这一段隐藏的问题比较多,修改的原因注释在旁边
(关注细节之前,最好先搞清楚它的流程,这样可以准确发现问题所在)
/******************************************************************************
* Function - Relative address offset
* Purpose - 计算第cx个逗号的相对地址偏移量
* Description - buf为字段的起始地址
*****************************************************************************/
u8 NMEA_Comma_Pos(u8 *buf,u8 cx)
{
u8 *p=buf;
while(cx)
{
if(*buf=='*'||*buf<' '||*buf>'z')/*排除*和非法字符*/
{
return 0XFF;
}
if(*buf==','){cx--;}
buf++;
}
return buf-p;/*相对地址偏移量*/
}
/******************************************************************************
* Function - Relative address offset
* Purpose - 计算每个语句结束符*的相对地址偏移量
* Description - buf为字段的起始地址
**************************************************************************/
u8 NMEA_End_Pos(u8 *buf)
{
u8 *p = buf;
while (*buf != '\n')
{
if (*buf<' ' || *buf>'z')/*排除非法字符*/
{
return 0XFF;
}
buf++;
}
return buf-p;/*相对地址偏移量*/
}
/******************************************************************************
* Function - Numeric character to digit
* Purpose - 数字字符转数字
* Description - buf为数字起始地址
**************************************************************************/
//数字字符转数字,扩大了很多倍,使其成为整数
int NMEA_Str2num(u8 *buf)
{
u8 *p=buf;/*buf为数字起始地址*/
u8 i,j,mask=0;/*mask作为负数号与小数点的验证标志*/
u8 ilen=0,flen=0;/*整数长和小数长*/
u32 ires=0,fres=0;/*整数和小数*/
int res;
while((*p!=',')&&(*p!='*')&&(*p!=' '))
{
/*if(*p=='-'){mask|=0x02;p++;}*//*进行按位或,mask=0x02是负数*/
if(*p=='.'){mask|=0x01;p++;}/*小数点*/
else if(*p>'9'||(*p<'0'))
{
ilen = 0;
flen = 0;
break;
}
if(mask&0x01){flen++;p++;}/*计数小数的位数*/
//这样计数小数点位数会把小数点也算进去 ,所以在最后相加的时候我把flen减了1
else{ilen++;p++;}/*起始检测存在数字*/
}
/*if(mask&0x02){flen++;}*//*负数符号位*/
for(i=0;i<ilen;i++)
{
ires+=NMEA_Pow(10,ilen-1-i)*(buf[i]-'0');/*buf为数字起始地址*/
}
if(flen>6){flen=6;}/*限定6位小数*/
for(j=0;j<flen;j++)
{
fres+=NMEA_Pow(10,flen-1-j)*(buf[ilen+1+j]-'0');/*加多1位小数点偏移量*/
}
//因为前面我把flen减一了,导致原本是整数的数乘以 NMEA_Pow(10,flen)无效,变成了0
//因此在此处重新加上对原本是整数的数的处理
if(flen)
res = ires*NMEA_Pow(10,flen-1)+fres;
else
res = ires*NMEA_Pow(10,flen)+fres;
/*if(mask&0x02)res=-res;*//*负数的情况*/
return res;
/******************************************************************************
* Function - NMEA Check bit calculation check
* Purpose - NMEA校验位计算检验
* Description - 按位异或计算'$'至'*'之间的字符
*************************************************************************/
//按位异或计算'$'至'*'之间的字符
int NMEA_Checkout(char str[256])
{
int i, result, value, avail;
char *tail;
tail = strstr(str, "*") + 1;
//若按照原来作者写的会把tail 后面的回车换行也一起转换,导致异或校验失败
//所以我把tail截断
*(tail+2)='\0';
value = NMEA_Str2hex2num(tail);
for (result = str[1], i = 2; str[i] != '*'; i++)
{
result ^= str[i];
}
if (result == value)
avail = 1;
else
avail = 0;
return avail;
}
}
上一篇: 使用OpenSSL库签署数字证书
下一篇: openssl 证书解析