C语言NMEA协议解析

lee38987808 2009-07-08 09:33:07
小弟菜鸟
用飞思卡尔DZ60做的串口程序,C语言
串口程序调通
串口功能是接收NMEA数据
经过解析后只留下&GPGGA………………*的数据
然后串口发送
现在串口程序调试完成,但是数据解析不会做,希望高手能提供个解析的代码。
因为真的非常非常着急!
谢谢了!!!
...全文
1402 34 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
34 条回复
切换为时间正序
请发表友善的回复…
发表回复
human0223 2012-04-09
  • 打赏
  • 举报
回复
[Quote=引用 33 楼 的回复:]

弱弱地问一下,怎么得到nmea的信息呢,要给gps发指令还是只接受
[/Quote]
只需要串口接收GPS数据就可以了.
yesterdaysky 2010-05-23
  • 打赏
  • 举报
回复
弱弱地问一下,怎么得到nmea的信息呢,要给gps发指令还是只接受
zhengxin051019 2010-04-02
  • 打赏
  • 举报
回复
要是用网络的形式实现GPS系统 需要什么协议?
sasuka 2010-03-17
  • 打赏
  • 举报
回复
http://git.koolu.org/?p=freerunner/platform/hardware/gps.git;a=blob;f=gps_freerunner.c;h=769409e060ea8a3d31a159520f082f443596ba53;hb=a5ea7613eb573281bf3be54d13093a0809055c47
各位大侠为何这个地址打不开啊?
dzq138 2009-11-09
  • 打赏
  • 举报
回复
http://git.koolu.org/?p=freerunner/platform/hardware/gps.git;a=blob;f=gps_freerunner.c;h=769409e060ea8a3d31a159520f082f443596ba53;hb=a5ea7613eb573281bf3be54d13093a0809055c47
留个脚印,我现在要解析NMEA...
自己写累,还是看看上面兄弟介绍的代码好些..
Nio96 2009-07-10
  • 打赏
  • 举报
回复
这可能就不是nmea解析的问题了。可能是你串口发送这一块有问题,你可以单独使用发送函数测试一下。做个假的数据组,循环地一直发送,看那边是否正常。打一些LOG出来,看问题出在什么地方。
lee38987808 2009-07-10
  • 打赏
  • 举报
回复
现在的情况时我第一次发一条GPGGA的数据能正确处理发送,再发第二次就发不出去,串口接的数据也不对
如果我发很多种数据GPGGA、GPGSA……的数据,另一个接收端就什么都收不到
Nio96 2009-07-10
  • 打赏
  • 举报
回复
。。。

你的数据不是从串口上报上来的吗?难道直接是一个buffer区?如果这样的话,你可以先将该buffer区置成你想要发送的GGA语句,先验证一下这样的情况你的语句能不能解析出来,能不能发送过去。如果这样OK了,再来考虑处理其他的情况。

另外,想问一下,你现在的问题是什么??
lee38987808 2009-07-10
  • 打赏
  • 举报
回复
以下为解析代码
//SCI1_order_str[]为解析后的有效数据,即GPGGA数据
//SCI1_order_counter为计数器
//SCI1_receive_data[]为全部数据
//SCI1_deal_counter为计数器

void GPS_data_analytic(void)
{
uchar checksum;
uchar c1,c2;
if(SCI1_comunication_bit==0)
{
if(SCI1_receive_data[SCI1_deal_counter]=='$')
{
SCI1_order_counter = 0;
SCI1_order_str[SCI1_order_counter++] = SCI1_receive_data[SCI1_deal_counter];
SCI1_deal_counter++;
SCI1_comunication_bit++;
}
else
{
DELAY_MS(1000);
//SCI1_deal_counter=0;
SCI1_comunication_bit=0;
SCI1_data_flag=0;
SCI1_order_counter=0;
SCI1_buffer_count=0;

return; //结束当前模块,返回上一层程序
}
}
else if(SCI1_comunication_bit==1)
{
if(SCI1_receive_data[SCI1_deal_counter]=='G')
{
SCI1_order_str[SCI1_order_counter++] = SCI1_receive_data[SCI1_deal_counter];
SCI1_deal_counter++;
SCI1_comunication_bit++;
}
else
{
DELAY_MS(1000);
//SCI1_deal_counter=0;
SCI1_comunication_bit=0;
SCI1_data_flag=0;
SCI1_order_counter=0;
SCI1_buffer_count=0;

return;
}
}

else if(SCI1_comunication_bit==2)
{
if(SCI1_receive_data[SCI1_deal_counter]=='P')
{
SCI1_order_str[SCI1_order_counter++] = SCI1_receive_data[SCI1_deal_counter];
SCI1_deal_counter++;
SCI1_comunication_bit++;
}
else
{
DELAY_MS(1000);
//SCI1_deal_counter=0;
SCI1_comunication_bit=0;
SCI1_data_flag=0;
SCI1_order_counter=0;
SCI1_buffer_count=0;

return;
}
}

else if(SCI1_comunication_bit==3)
{
if(SCI1_receive_data[SCI1_deal_counter]=='G')
{
SCI1_order_str[SCI1_order_counter++] = SCI1_receive_data[SCI1_deal_counter];
SCI1_deal_counter++;
SCI1_comunication_bit++;
}
else
{
DELAY_MS(1000);
SCI1_deal_counter=0;
SCI1_comunication_bit=0;
SCI1_data_flag=0;
SCI1_order_counter=0;
SCI1_buffer_count=0;

return;
}
}

else if(SCI1_comunication_bit==4)
{
if(SCI1_receive_data[SCI1_deal_counter]=='G')
{
SCI1_order_str[SCI1_order_counter++] = SCI1_receive_data[SCI1_deal_counter];
SCI1_deal_counter++;
SCI1_comunication_bit++;
}
else
{
DELAY_MS(1000);
//SCI1_deal_counter=0;
SCI1_comunication_bit=0;
SCI1_data_flag=0;
SCI1_order_counter=0;
SCI1_buffer_count=0;

return;
}
}

else if(SCI1_comunication_bit==5)
{
if(SCI1_receive_data[SCI1_deal_counter]=='A')
{
SCI1_order_str[SCI1_order_counter++] = SCI1_receive_data[SCI1_deal_counter];
SCI1_deal_counter++;
SCI1_comunication_bit++;
}
else
{
DELAY_MS(1000);
//SCI1_deal_counter=0;
SCI1_comunication_bit=0;
SCI1_data_flag=0;
SCI1_order_counter=0;
SCI1_buffer_count=0;

return;
}
}

else if(SCI1_comunication_bit==6)
{
if(SCI1_receive_data[SCI1_deal_counter]==LF)
{
SCI1_order_str[SCI1_order_counter]=SCI1_receive_data[SCI1_deal_counter];
Check_H=SCI1_receive_data[SCI1_order_counter-3];
Check_L=SCI1_receive_data[SCI1_order_counter-2];
checksum=Data_Check_Sum(SCI1_order_str, SCI1_order_counter);
c2=checksum & 0x0f;
c1=((checksum>>4) & 0x0f);
if(c1<10) c1+='0'; else c1+='A'-10;
if(c2<10) c2+='0'; else c2+='A'-10;
if((c1==Check_H)&&(c2==Check_L))
{
do_SCI1_order_bit=1;
SCI1_comunication_bit=0;
SCI1_data_flag=0;
}
else
{
SCI1_SEND('A');
//SCI1_comunication_bit=0;
SCI1_order_counter=0;
SCI1_data_flag=0;
}

}
else
{
SCI1_order_str[SCI1_order_counter++] = SCI1_receive_data[SCI1_deal_counter];
SCI1_deal_counter++;
}
}

else //上面任何一帧不对,都重新置0
{
SCI1_comunication_bit=0;
SCI1_order_counter=0;
}
}
Nio96 2009-07-10
  • 打赏
  • 举报
回复
或者还是可以参考上面给你发的代码,解析出来token之后,使用(memcmp(tok.p,"GGA",3))来判断是不是GGA语句就行了。
Nio96 2009-07-10
  • 打赏
  • 举报
回复
那你直接判断你的语句头就行了啊。判断前五个字符为$GPGGA,以下一个$为结束符就行了啊,把它置成'\0'。再发送就OK了啊。
如果还是不明白的话,把你的相关部分wad代码贴出来看看。
lee38987808 2009-07-10
  • 打赏
  • 举报
回复
是这样
我以个缓冲区接收到如下数据
$GPGSA,A,1,24,10,09,,,,,,,,,,,,*10
$GPRMC,030018.992,V,4346.3692,N,12524.9660,E,,,190509,,,N*78
$GPGGA,030019.995,4346.3584,N,12524.9686,E,1,03,10.9,223.3,M,12.5,M,,0000*61
$GPGSA,A,2,24,10,09,,,,,,,,,,10.9,10.9,1.0*3C
$GPRMC,030019.995,A,4346.3584,N,12524.9686,E,0.00,,190509,,,A*74
$GPGGA,030020.995,4346.3522,N,12524.9766,E,1,04,3.6,232.3,M,12.5,M,,0000*52
$GPGSA,A,3,24,10,09,27,,,,,,,,,3.7,3.6,1.0*39
$GPRMC,030020.995,A,4346.3522,N,12524.9766,E,0.95,337.22,190509,,,A*68
$GPGGA,030021.995,4346.3565,N,12524.9639,E,1,05,2.5,204.4,M,12.5,M,,0000*5A
$GPGSA,A,3,24,10,09,21,27,,,,,,,,3.7,2.5,2.7*3C
然后从中把第一条GPGGA数据取出来存到另一个缓冲区中,例如GPGGA_data[128]
最后把GPGGA_data[128]发出去
Sou2012 2009-07-10
  • 打赏
  • 举报
回复
帮顶!
rabbitjerry 2009-07-09
  • 打赏
  • 举报
回复
帮顶~
Nio96 2009-07-09
  • 打赏
  • 举报
回复
这样是吧。给你个思路。
char * b_Sentence[NMEA_MSG_LENGTH], *P_Buf = bSentence;
//如果为空的话那么:
p_Buf +=std_sprintf(p_Buf,sizeof(b_Sentence),"$GPGGA,,,,,0,,,,");
//这里进行nmea数据字段的获取,如时间啊,经度纬度什么的,你就自己根据设置上报上来的就行了。
//获取之后,再封装如下:
p_B += std_sprintf(p_Buf,sizeof(b_Sentence),"$GPGGA,%02ld%02ld%02ld.%01ld,",Hours,Mins,Secs,Tenths);

再把经纬度等类似封装。。。

再把后缀什么的加上。

再用你的串口函数进行发送,如:
NmeaSentenceTerminateSend(b_sentence);
文刀劉Michael 2009-07-09
  • 打赏
  • 举报
回复
up up up
lee38987808 2009-07-09
  • 打赏
  • 举报
回复
我的意思是:
一条NMEA数据不是包括$GPGGA、&GPRMC、&GPGSA、&GPGSV这些数据吗
串口接收时给一定的时间不断接受NMEA数据,包括以上类型
然后我从这所有的数据中解析出第一条&GPGGA数据后保存在一个缓冲区中,再从串口发出去
发送前不对&GPGGA中的数据做详细解析
发送完毕后清空缓冲区再进行下一次收发
K_s_G 2009-07-09
  • 打赏
  • 举报
回复
顶顶
Nio96 2009-07-09
  • 打赏
  • 举报
回复
你的意思是你的是原始数据,想要解析成nmea数据再上报?
amossavez 2009-07-09
  • 打赏
  • 举报
回复
这个帮顶!
加载更多回复(14)

70,020

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧