27,382
社区成员
发帖
与我相关
我的任务
分享
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;
}
}
}
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;