有木有会Delphi的大牛!!!

a298028549 2011-12-31 10:44:24
**************************************************
GPS上位机接收部分代码
**************************************************

procedure TGPSForm.MSComm2Comm(Sender: TObject);
var
dta,dta1,tmp:string;
i,j:integer;
begin
dta:= MSComm2.Input;
Timer2.Enabled:=False;
Timer2.Enabled:=True;
if dta='$' then begin
b:=dta;
exit;
end;
if dta=chr(10) then begin
b:=b+dta;
if pos('$GPRMC',b)<>0 then
if pos('A',b)<>0 then begin
try
Image1.Visible:=True;
Image2.Visible:=False;
a:=copy(b,pos(',',b)+1,6);
a:=copy(a,1,2)+':'+copy(a,3,2)+':'+copy(a,5,6);
j:=pos(',',b);
dta1:=copy(b,J+1,length(b));
for i:=1 to 8 do begin
j:=pos(',',dta1);
dta1:=copy(dta1,j+1,length(b));
end;
c:=copy(dta1,1,6);
c:=copy(c,5,2)+'-'+copy(c,3,2)+'-'+copy(c,1,2);
tmp:=timetostr(strtotime(a)+strtotime('08:00:00'));
if (strtotime(a)>strtotime('00:00:00') ) and (strtotime(a)<strtotime('16:00:00'))then
Panel2.Caption:=DateToStr(strtodate(c))+' '+tmp
else
Panel2.Caption:=DateToStr(strtodate(c)+1)+' '+tmp;
if SpeedButton1.Down then begin//调整PC时间
SetPCSystemTime(StrToDateTime(Panel2.Caption));
end;
except
end;
//经纬度
try
j:=pos('A,',b);
dta1:=copy(b,j+2,length(b));
j:=pos(',',dta1);
tmp:=copy(dta1,1,J-1);
dta1:=copy(dta1,j+1,length(dta1));
tmp:=dta1[1]+':'+FormatFloat('0.000',StrToFloat(tmp)/100);
delete(dta1,1,2);
j:=pos(',',dta1);
dta1:=copy(dta1,1,J+1);
tmp:=tmp+' '+rightstr(dta1,1)+':'+FormatFloat('0.000',StrToFloat(copy(dta1,1,J-1))/100);
Panel3.Caption:=tmp;
except
Panel3.Caption:='E:--- N:---';
end;
exit;
end else begin
Image2.Visible:=True;
Image1.Visible:=False;
b:=' ';
exit;
end;
b:='';
exit;
end;
b:=b+dta;
end;


求大牛们,帮我写下注释,或者程序运行的步骤帮我写下,谢谢了!我要把这个写成C语言
...全文
66 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
woshi_ziyu 2011-12-31
  • 打赏
  • 举报
回复
[Quote=引用楼主 a298028549 的回复:]
**************************************************
GPS上位机接收部分代码
**************************************************

procedure TGPSForm.MSComm2Comm(Sender: TObject);
var
dta,dta1,tmp:string;
i……
[/Quote]
有很多C语言的代码 何必跟他过不去呢
skylkj 2011-12-31
  • 打赏
  • 举报
回复
就是从串口接收gps数据,然后解析的程序


pos函数的作用是查询字串在母串中的位置,比如
if pos('$GPRMC',b)<>0 then
就是在b中找有没有$GPRMC

copy就是内存拷贝,截取字符串用的。

程序基本就是字符串处理,你了解gps数据的格式的话,完全可以自己写,根本不用参考这个delphi程序
a298028549 2011-12-31
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 skylkj 的回复:]
以前项目同事写的。他判断RMC包头是在函数外,就不贴了,类似的
这个写法没问题,不过不太直观。换了我我不会这样写

程序逻辑是收全一条gps语句,然后从头遍历,找第N和第N+1个逗号。这之间的就是一个数据。详见上面的RMC包格式。
代码只贴了部分,只是给你看个意思,不是让你直接拷贝过去用的

谢谢,我程序写好了的,也试验OK了的(实物),不会抄的,就是需要看下上位机的接收程序的通信协议,和上位机的处理过程,把我的程序过程完善下,做的严谨点,谢谢这位大牛的帮助,真心感谢!!

a298028549 2011-12-31
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 skylkj 的回复:]
以前项目同事写的。他判断RMC包头是在函数外,就不贴了,类似的
这个写法没问题,不过不太直观。换了我我不会这样写

程序逻辑是收全一条gps语句,然后从头遍历,找第N和第N+1个逗号。这之间的就是一个数据。详见上面的RMC包格式。
代码只贴了部分,只是给你看个意思,不是让你直接拷贝过去用的


C/C++ code

bool lbt_get_gps_position_info(……
[/Quote]



en ,谢谢,我单片机接收程序已经写好了的,并且实际电路上已经OK了的,但是现在要和上位机通讯,把我收到的信息发给上位机,看过您给我注释的程序了,我只要发收到的gps语句直接转发就好了呢,不用做处理,谢谢了,不过你们的程序确实比我严谨!谢谢了
skylkj 2011-12-31
  • 打赏
  • 举报
回复
以前项目同事写的。他判断RMC包头是在函数外,就不贴了,类似的
这个写法没问题,不过不太直观。换了我我不会这样写

程序逻辑是收全一条gps语句,然后从头遍历,找第N和第N+1个逗号。这之间的就是一个数据。详见上面的RMC包格式。
代码只贴了部分,只是给你看个意思,不是让你直接拷贝过去用的


bool lbt_get_gps_position_info(u8* gps_pos_packet, u16 packet_len, lbt_gps_info* pos_info)
{
u8 sep = ',';
u16 p1=0;
u16 p2=0;
u8 unit_count = 0;
u8 speed[10] = {0};
u8 time[12] = {0};
u8 longitude[16] = {0};
u8 latitude[16] = {0};
u8 direction[7] = {0};
double d_longitude = 0;
double d_latitude = 0;
static u8 isstatic = 2;
unsigned short temp_direction = 0;
static short p_direction = -1;
double d_radian = 0.0;

p1 = find_char(gps_pos_packet,sep, packet_len);
if(p1 == 0)
{
return FALSE;
}

while(p1 < packet_len)
{
p2 = find_char(gps_pos_packet+p1,sep, packet_len-p1);
switch(unit_count)
{
case 0: //time: hhmmss.ss
{
if(p2 != 10)
{
return FALSE;
}
else
{
memset(time, 0, 12);
memcpy(time+6, gps_pos_packet+p1, 6);
}
break;
}
case 1: //定位状态
{
if( p2!= 2)
{
return FALSE;
}

if(*(gps_pos_packet+p1) == 'V')
{
if(__lbt_gps_locate_off_count<30)
{
__lbt_gps_locate_off_count++;
}
return FALSE;
}
else
{
__lbt_gps_locate_off_count = 0;
}
break;
}
case 2: //Latitude
{
if(p2 < 10)
{
return FALSE;
}
else
{
memset(latitude, 0 , 16);
memcpy(latitude, gps_pos_packet+p1, 9);
}
break;
}
case 3: //N/S
{
if(p2!=2)
{
return FALSE;
}
break;
}
case 4: //longitude
{
if(p2 < 11)
{
return FALSE;
}
else
{
memset(longitude, 0 , 16);
memcpy(longitude, gps_pos_packet+p1, 10);
}
break;
}
case 5: //W/E
{
if(p2!=2)
{
return FALSE;
}
break;
}
case 6: //speed
{
if(p2 <= 7) //20110106
{
memset(speed, 0 , 10);
//memcpy(speed, gps_pos_packet+p1, 6);
memcpy(speed, gps_pos_packet+p1, p2-1); //20101229
uart_printf("RMC speed:%s\r\n",speed);
break;
}
}
case 7: //direction
{
if(p2 <= 7) //20110106
{
memset(direction, 0 , 7);
memcpy(direction, gps_pos_packet+p1, 6);

temp_direction = atoi((char*)direction);
uart_printf("temp_direction:%d\r\n",temp_direction);
pos_info->direction = temp_direction/2;
}
break;
}
case 8: //date: ddmmyy
{
if(p2 != 7)
{
return FALSE;
}
else
{
memcpy(time, gps_pos_packet+p1, 6);
}
break;
}
case 9: //磁偏角
case 10: //磁偏角 W/E
case 11: //模式指示 A=自主定位,D=差分,E=估算,N=数据无效
default:
break;
}
p1 += p2;
if(unit_count++ >= 8)
{
break;
}
}
}


a298028549 2011-12-31
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 skylkj 的回复:]
引用 5 楼 a298028549 的回复:

哎,,领导做得上位机啊啊,,我们这些小打工,只能配合啊,,只能解析领导的上位机程序写下位机啊,,伤不起啊,,有木有啊!!!1


单纯从这段程序看,只是解析标准的gps语句,按理说你下位机不用做任何事去配合这段上位机程序,只要把gps发出的数据全丢给串口就行了
[/Quote]

他说我写得不严谨,,要我参照他的写,,还有,,大哥能把他接收的通讯协议帮我看下么,帮我写出来下,谢谢了
skylkj 2011-12-31
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 a298028549 的回复:]

哎,,领导做得上位机啊啊,,我们这些小打工,只能配合啊,,只能解析领导的上位机程序写下位机啊,,伤不起啊,,有木有啊!!!1
[/Quote]

单纯从这段程序看,只是解析标准的gps语句,按理说你下位机不用做任何事去配合这段上位机程序,只要把gps发出的数据全丢给串口就行了
skylkj 2011-12-31
  • 打赏
  • 举报
回复
附RMC包数据格式

$GPRMC,<1>,<2>,<3>,<4>,<5>,<6>,<7>,<8>,<9>,<10>,<11>,<12>*hh<CR><LF>
  各字段的含义和取值范围见表5所示。
表5 $GPRMC语句各字段的含义和取值范围
字段 含义 取值范围
<1> UTC时间, hhmmss.ss 000000.00~235959.99
<2> 定位状态 A=有效定位,V=无效定位
<3> 纬度,格式:ddmm.mmmm 000.00000~8959.9999
<4> 南北半球 N表示北纬;S表示南纬
<5> 经度格式dddmm.mmmm 00000.0000~17959.9999
<6> 东西半球 E表示东经;W表示西经
<7> 地面速率 000.0~999.9节
<8> 地面航向 000.0~359.9,以真北为参考基准
<9> UTC日期,格式:ddmmyy 日月年
<10> 磁偏角 000.0~180.0度
<11> 磁偏角 E表示偏东;W表示偏西
<12> 模式指示(NMEA0183 3.00版本输出) A=自主定位,D=差分,E=估算,N=数据无效
  例句:
  $GPRMC,074529.82,A,2429.6717,N,11804.6973,E,12.623,32.122,010806,,W,A*08
skylkj 2011-12-31
  • 打赏
  • 举报
回复


procedure TGPSForm.MSComm2Comm(Sender: TObject);
var
dta,dta1,tmp:string;
i,j:integer;
begin
//mscomm是ms的串口控件,这里是读串口一个字符
dta:= MSComm2.Input;

{
timer2是个定时器,这里重置了timer2
猜测timer2类似一个看门狗,timer2触发之前不重置的话就会触发timer2的事件
应该是个超时处理
}
Timer2.Enabled:=False;
Timer2.Enabled:=True;


if dta='$' then //如果接受到的字符串是 $ (gps上传数据都以$开头)
begin
//b是全局变量,存放一条gps语句。单字母做全局变量,菜鸟
//如果收到的是$,则重置b,作为一条新的gps语句
b:=dta;
exit; //退出函数,等同于return
end;


if dta=chr(10) then //如果收到字符是换行LF(0x0a) LF是gps语句结束符,如果收到LF,则可以进行语句解析了
begin
b:=b+dta;
if pos('$GPRMC',b)<>0 then //如果当前gps语句是RMC语句
if pos('A',b)<>0 then //如果当前gps语句里有字符'A'
//这里可能会有bug,程序本意应该是看RMC数据里的定位状态,A为有效,V为无效
//所以这里的判断是当前gps数据是否有效
//但RMC包最后也有个模式指示,如果是自主定位的话也是A,所以在使用不同gps时,这里可能会错误的解析非法gps数据包
begin
try //delphi的异常机制,如果try里的语句出异常,则跳转到except部分执行

Image1.Visible:=True; //显示image1
Image2.Visible:=False; //隐藏image2
//结合最后的显示,这里应该是一个图片提示,收到有效gps包时显示image1,否则显示image2

//取gps语句第一个逗号后的6个字符到全局变量a,菜鸟
//实际就是取gps时间,详见gps RMC包格式
a:=copy(b,pos(',',b)+1,6);

//将时间由hhmmss转换成hh:mm:ss
a:=copy(a,1,2)+':'+copy(a,3,2)+':'+copy(a,5,6);

//截取gps语句第一个逗号之后的部分到dta1
j:=pos(',',b);
dta1:=copy(b,J+1,length(b));

//同样的蠢事做8次
for i:=1 to 8 do
begin
j:=pos(',',dta1);
dta1:=copy(dta1,j+1,length(b));
end;
//干过9次蠢事后,此时的gps语句开头应该是日期信息

//取gps日期信息(ddmmyy)到c,菜鸟
c:=copy(dta1,1,6);
//将日期由ddmmyy转换为yy-mm-dd
c:=copy(c,5,2)+'-'+copy(c,3,2)+'-'+copy(c,1,2);

//tmp为完整日期+时间
//这里感觉应该弄错了,应该是strtotime(c)而不是strtotime(a)
tmp:=timetostr(strtotime(a)+strtotime('08:00:00'));

//如果时间在16点前
if (strtotime(a)>strtotime('00:00:00') ) and (strtotime(a)<strtotime('16:00:00'))then
Panel2.Caption:=DateToStr(strtodate(c))+' '+tmp //尼玛的strtodate再DateToStr好玩啊?
else
Panel2.Caption:=DateToStr(strtodate(c)+1)+' '+tmp;

if SpeedButton1.Down then begin//调整PC时间
SetPCSystemTime(StrToDateTime(Panel2.Caption));
end;
except //出异常了什么都不做,仅仅只是为了防止程序奔溃.
end;

//经纬度
try

//取纬度,详见RMC数据格式
j:=pos('A,',b);
dta1:=copy(b,j+2,length(b)); //这里会多拷贝b串后的两个字节数据,相当于数组越界了.菜鸟

//下面一堆字符串处理,懒得看了,就是把经纬度取出来显示到Panel3的标题上
j:=pos(',',dta1);
tmp:=copy(dta1,1,J-1);
dta1:=copy(dta1,j+1,length(dta1));
tmp:=dta1[1]+':'+FormatFloat('0.000',StrToFloat(tmp)/100);
delete(dta1,1,2);
j:=pos(',',dta1);
dta1:=copy(dta1,1,J+1);
tmp:=tmp+' '+rightstr(dta1,1)+':'+FormatFloat('0.000',StrToFloat(copy(dta1,1,J-1))/100);
Panel3.Caption:=tmp;
except //解析异常则清空经纬度显示
Panel3.Caption:='E:--- N:---';
end;

exit;
end
else
begin
Image2.Visible:=True;
Image1.Visible:=False;
b:=' ';
exit;
end;

b:='';
exit;
end;

//如果既不是gps开头字符$,又不是结束符LF,则将字符拼接到当前gps语句的最后
b:=b+dta;
end;


a298028549 2011-12-31
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 northcan 的回复:]
呵呵。“聪明的人用Delphi”,CSDN有专门的Delphi板块,在开发语言那里,还是去那问吧。
[/Quote]

去那里发帖子了,至今无人回复啊,。。
a298028549 2011-12-31
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 woshi_ziyu 的回复:]
引用楼主 a298028549 的回复:
**************************************************
GPS上位机接收部分代码
**************************************************

procedure TGPSForm.MSComm2Comm(Sender: TObject);
var
dta……
[/Quote]

去那里发帖子了,,至今无人回复。。。
a298028549 2011-12-31
  • 打赏
  • 举报
回复
哎,,领导做得上位机啊啊,,我们这些小打工,只能配合啊,,只能解析领导的上位机程序写下位机啊,,伤不起啊,,有木有啊!!!1
northcan 2011-12-31
  • 打赏
  • 举报
回复
呵呵。“聪明的人用Delphi”,CSDN有专门的Delphi板块,在开发语言那里,还是去那问吧。

27,382

社区成员

发帖
与我相关
我的任务
社区描述
硬件/嵌入开发 单片机/工控
社区管理员
  • 单片机/工控社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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