L
liuql188
Unregistered / Unconfirmed
GUEST, unregistred user!
这是我的garmin手持机接收程序,后面是运行结果,
为什么接受的长度多数是64,极少数是63,并且长度是63的,解析后的name少一个字符,alt,dpth也不正确。
程序源码:
====================
type
TGPSWayPoint = class
Name : string;
comment : string;
wpt_class : byte;
color : byte;
dspl : byte;
Alt : single;
dpth : single;
Dist : single;
attr : byte;
smbl : word;
X : single;
Y : single;
private
public
{ Public declarations }
end;
Packet_t = record
mPacketType:char;
mReserved1:char;
mReserved2:word;
mPacketId:word;
mReserved3:word;
mDataSize:Longword ;
mData: array of byte;
end;
TGarminGPSForm = class(TForm)
Comm1: TComm;
Dbf1: TDbf;
DataSource1: TDataSource;
DBGrid1: TDBGrid;
Memo1: TMemo;
Panel1: TPanel;
open: TButton;
close: TButton;
Button1: TButton;
Button2: TButton;
Splitter1: TSplitter;
procedure SendACK(RecByte : Byte);
function CalcCheckSum(var sPack : string) : integer;
function GetCoordinate(Semicircle : string) :do
uble;
//4 char
procedure Translate_D108_Wpt_type(Package : string);
function GetIntData(strData: string;
nbegin
Pos, nLength: integer): integer;
function FixPackage(var sPack:string ):integer
function unFixPackage(var sPack : string) : integer;
function GetSingleData(sPack:string;pos,len:integer):single;
procedure openClick(Sender: TObject);
procedure closeClick(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure Comm1ReceiveData(Sender: TObject;
Buffer: Pointer;
BufferLength: Word);
procedure Button2Click(Sender: TObject);
procedure showmsg(fx,str:string);
private
{ Private declarations }
public
{ Public declarations }
end;
var
GarminGPSForm: TGarminGPSForm;
implementation
{$R *.dfm}
procedure TGarminGPSForm.showmsg(fx,str:string);
var str1:string;
i:integer;
begin
str1:=fx;
for i:= 1 to length(str)do
str1:=str1+inttohex(ord(str),1);
memo1.Lines.Append(str1);
end;
function TGarminGPSForm.GetSingleData(sPack:string;pos,len:integer):single;
var
buf : array[0..3] of byte;
begin
buf[0] := ord(sPack[pos]);
Buf[1] := ord(sPack[pos+1]);
Buf[2] := ord(sPack[pos+2]);
Buf[3] := ord(sPack[pos+3]);
Move(Buf, result, 4);
end;
procedure TGarminGPSForm.Translate_D108_Wpt_type(Package : string);
var
XX,YY :do
uble;
WPt : TGPSWayPoint;
//航点类,没什么特别的,你可以设计你自己的。
szSubPack : string;
maxID:integer;
begin
WPt := TGPSWayPoint.Create;//建一个航点实例
szSubPack:=Copy(Package,52,length(Package)-48);//取航点名称,可以是中文,注意有可能有很多空格,早期etrex大概只有5个汉字,而后期的和航海GPS可能有很长的中文名
Wpt.Name := Copy(szSubPack, 1, Pos(#0, szSubPack) - 1);
Wpt.Name := Trim(Wpt.Name);
Delete(szSubPack, 1, Pos(#0, szSubPack));
wpt.comment := Copy(szSubPack, 1, Pos(#0, szSubPack) - 1);//取其中的备注部分,一般是空的,Vista可能会把建立航点的时间写在这里。
Wpt.wpt_class := Ord(Package[4]);
wpt.color := Ord(Package[5]);
wpt.dspl := Ord(Package[6]);
wpt.Alt := GetSingleData(Package,36,4);
if Wpt.Alt > 10E10 then
Wpt.Alt := 0;
wpt.dpth := GetSingleData(Package,40,4);
if Wpt.Dpth > 10E10 then
Wpt.Dpth := 0;
wpt.Dist := GetSingleData(Package,44,4);
if Wpt.Dist > 10E10 then
Wpt.Dist := 0;
{
dspl_name = 0, /* Display symbol with waypoint name */
dspl_none = 1, /* Display symbol by itself */
dspl_cmnt = 2 /* Display symbol with comment */
}
wpt.attr := Ord(Package[7]);
{ The "attr"
member should be set to a value of 0x60.}
wpt.smbl := GetIntData(Package,8,2);
YY := GetCoordinate(Copy(Package,28,4));
XX := GetCoordinate(Copy(Package,32,4));
//WPt.AddPt(XX,YY);
dbf1.Append;
dbf1.FieldByName('id').AsInteger:=1;
dbf1.FieldByName('name').asstring:=wpt.Name;
dbf1.FieldByName('comment').AsString:=wpt.comment;
dbf1.FieldByName('wpt_class').AsInteger:=wpt.wpt_class;
dbf1.FieldByName('color').asinteger:=wpt.color;
dbf1.FieldByName('dspl').AsInteger:=wpt.dspl;
dbf1.FieldByName('alt').AsFloat:=wpt.Alt;
dbf1.FieldByName('dpth').AsFloat:=wpt.dpth;
dbf1.FieldByName('dist').AsFloat:=wpt.dist;
dbf1.FieldByName('attr').AsInteger:=wpt.attr;
dbf1.FieldByName('xx').asfloat:=xx;
dbf1.FieldByName('yy').asfloat:=yy;
dbf1.Post;
end;
//从报文中解析坐标
function TGarminGPSForm.GetCoordinate(Semicircle : string) :do
uble;
//4 char
begin
if semicircle='' then
result:=0
else
result := (Ord(SemiCircle[1]) + Ord(SemiCircle[2]) * Power(2,8) + Ord(SemiCircle[3]) * Power(2,16) + Ord(SemiCircle[4]) * Power(2,24)) * 180/Power(2,31);
end;
//根据字节计算出整数来
function TGarminGPSForm.GetIntData(strData: string;
nbegin
Pos, nLength: integer): integer;
var
I : integer;
begin
result := 0;
for I := 1 to nLengthdo
begin
result := result + Round(Ord(StrData[nbegin
Pos + (I - 1)]) * Power(2,8 * (I - 1)));
end;
end;
procedure TGarminGPSForm.SendACK(RecByte : Byte);
var
sPack : string;
begin
sPack := #16;
sPack := sPack + Chr(Pid_Ack_Byte);
sPack := sPack + #2;
sPack := sPack + Chr(RecByte);
sPack := sPack + #0#0#16#3;
CalcCheckSum(sPack);
comm1.WriteCommData(pchar(sPack),length(sPack));
end;
function TGarminGPSForm.CalcCheckSum(var sPack : string) : integer;
var
nCheckByte : Byte;
I : integer;
begin
try
nCheckByte := 0;
for I := 0 to Ord(sPack[3])do
begin
nCheckByte := nCheckByte + Ord(sPack[I + 2]);
end;
sPack[4 + Ord(sPack[3])] := Chr(256 - nCheckByte);
result := Ord(sPack[4 + Ord(sPack[2])]);
//#16->#16#16
FixPackage(sPack);
except
end;
end;
function TGarminGPSForm.FixPackage(var sPack : string) : integer;
//#16->#16#16
var
n:integer;
I : integer;
str1:string;
begin
try
n:=0;
str1:=sPack;
sPack:=#16;
for I := 2 to length(str1)-2do
begin
if str1=#16 then
begin
//若是#16,则先插入一个
sPack:=sPack+#16;
n:=n+1;
end;
sPack:=sPack+str1;
end;
sPack:=sPack+#16#3;
result := n;
except
end;
end;
function TGarminGPSForm.unFixPackage(var sPack : string) : integer;
//#16#16->#16
var
n:integer;
I : integer;
str1:string;
begin
try
n:=0;
str1:=sPack;
sPack:=#16;
for I := 2 to length(str1)-2do
begin
if (str1=#16) and (str1[i+1]=#16) then
begin
//若是连续两个#16,则放弃第一个
n:=n+1;
end
else
sPack:=sPack+str1;
end;
sPack:=sPack+#16#3;
result := n;
except
end;
end;
procedure TGarminGPSForm.openClick(Sender: TObject);
begin
comm1.StartComm;
end;
procedure TGarminGPSForm.closeClick(Sender: TObject);
begin
comm1.StopComm;
end;
procedure TGarminGPSForm.Button1Click(Sender: TObject);
var
i: integer;
cmd:string;
begin
cmd:=#16;
cmd:=cmd+chr(Pid_Command_Data);
cmd := cmd + #2;
cmd := cmd + Chr(Cmnd_Transfer_Wpt);
cmd := cmd + #0#0#16#3;
calcCheckSum(cmd);
showmsg('W:',cmd);
comm1.WriteCommData(pansichar(cmd),length(cmd));
end;
procedure TGarminGPSForm.Comm1ReceiveData(Sender: TObject;
Buffer: Pointer;
BufferLength: Word);
var
frambuf:string;
ppchar;
i: integer;
begin
frambuf:='';
// memo1.Lines.Append('正在接收串口数据...');
pp:=buffer;
for i:=1 to bufferlengthdo
begin
frambuf:=frambuf+pp^;
pp:=pp+1;
end;
unFixPackage(frambuf);
showmsg('R:<'+inttostr(bufferlength)+'-'+inttostr(length(frambuf))+'> ',frambuf);
showmsg('W:',frambuf[2]);
sendAck(ord(frambuf[2]));
if frambuf[2]=#35 then
begin
Translate_D108_Wpt_type(frambuf);
end;
end;
====================================
运行结果:
R:<64-64> 10233A0FF060120000000FFFFFFFFFFFFFFFFFFFFFFFF6718621BD20A2510CB71425159469515946920202020303133320000008B103
W:23
R:<64-64> 10233A0FF060120000000FFFFFFFFFFFFFFFFFFFFFFFF72FA611BA8E9A151E0677B425159469515946920202020303133330000005A103
W:23
R:<64-64> 10233A0FF060120000000FFFFFFFFFFFFFFFFFFFFFFFFB5D1611B8D3A151E02D684251594695159469202020203031333400000042103
W:23
R:<64-64> 10233A0FF060120000000FFFFFFFFFFFFFFFFFFFFFFFFEFAA611BE5C4A1510CB714251594695159469202020203031333500000099103
W:23
R:<64-64> 10233A0FF060120000000FFFFFFFFFFFFFFFFFFFFFFFF3888611BD1AEA1510CB71425159469515946920202020303133360000009B103
W:23
R:<63-63> 10233A0FF060120000000FFFFFFFFFFFFFFFFFFFFFFFF5560611B3C97A151408142515946951594692020202030313337000000BB103
W:23
R:<64-64> 10233A0FF060120000000FFFFFFFFFFFFFFFFFFFFFFFF862E611B387BA151D0ED904251594695159469202020203031333800000060103
W:23
为什么接受的长度多数是64,极少数是63,并且长度是63的,解析后的name少一个字符,alt,dpth也不正确。
程序源码:
====================
type
TGPSWayPoint = class
Name : string;
comment : string;
wpt_class : byte;
color : byte;
dspl : byte;
Alt : single;
dpth : single;
Dist : single;
attr : byte;
smbl : word;
X : single;
Y : single;
private
public
{ Public declarations }
end;
Packet_t = record
mPacketType:char;
mReserved1:char;
mReserved2:word;
mPacketId:word;
mReserved3:word;
mDataSize:Longword ;
mData: array of byte;
end;
TGarminGPSForm = class(TForm)
Comm1: TComm;
Dbf1: TDbf;
DataSource1: TDataSource;
DBGrid1: TDBGrid;
Memo1: TMemo;
Panel1: TPanel;
open: TButton;
close: TButton;
Button1: TButton;
Button2: TButton;
Splitter1: TSplitter;
procedure SendACK(RecByte : Byte);
function CalcCheckSum(var sPack : string) : integer;
function GetCoordinate(Semicircle : string) :do
uble;
//4 char
procedure Translate_D108_Wpt_type(Package : string);
function GetIntData(strData: string;
nbegin
Pos, nLength: integer): integer;
function FixPackage(var sPack:string ):integer
function unFixPackage(var sPack : string) : integer;
function GetSingleData(sPack:string;pos,len:integer):single;
procedure openClick(Sender: TObject);
procedure closeClick(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure Comm1ReceiveData(Sender: TObject;
Buffer: Pointer;
BufferLength: Word);
procedure Button2Click(Sender: TObject);
procedure showmsg(fx,str:string);
private
{ Private declarations }
public
{ Public declarations }
end;
var
GarminGPSForm: TGarminGPSForm;
implementation
{$R *.dfm}
procedure TGarminGPSForm.showmsg(fx,str:string);
var str1:string;
i:integer;
begin
str1:=fx;
for i:= 1 to length(str)do
str1:=str1+inttohex(ord(str),1);
memo1.Lines.Append(str1);
end;
function TGarminGPSForm.GetSingleData(sPack:string;pos,len:integer):single;
var
buf : array[0..3] of byte;
begin
buf[0] := ord(sPack[pos]);
Buf[1] := ord(sPack[pos+1]);
Buf[2] := ord(sPack[pos+2]);
Buf[3] := ord(sPack[pos+3]);
Move(Buf, result, 4);
end;
procedure TGarminGPSForm.Translate_D108_Wpt_type(Package : string);
var
XX,YY :do
uble;
WPt : TGPSWayPoint;
//航点类,没什么特别的,你可以设计你自己的。
szSubPack : string;
maxID:integer;
begin
WPt := TGPSWayPoint.Create;//建一个航点实例
szSubPack:=Copy(Package,52,length(Package)-48);//取航点名称,可以是中文,注意有可能有很多空格,早期etrex大概只有5个汉字,而后期的和航海GPS可能有很长的中文名
Wpt.Name := Copy(szSubPack, 1, Pos(#0, szSubPack) - 1);
Wpt.Name := Trim(Wpt.Name);
Delete(szSubPack, 1, Pos(#0, szSubPack));
wpt.comment := Copy(szSubPack, 1, Pos(#0, szSubPack) - 1);//取其中的备注部分,一般是空的,Vista可能会把建立航点的时间写在这里。
Wpt.wpt_class := Ord(Package[4]);
wpt.color := Ord(Package[5]);
wpt.dspl := Ord(Package[6]);
wpt.Alt := GetSingleData(Package,36,4);
if Wpt.Alt > 10E10 then
Wpt.Alt := 0;
wpt.dpth := GetSingleData(Package,40,4);
if Wpt.Dpth > 10E10 then
Wpt.Dpth := 0;
wpt.Dist := GetSingleData(Package,44,4);
if Wpt.Dist > 10E10 then
Wpt.Dist := 0;
{
dspl_name = 0, /* Display symbol with waypoint name */
dspl_none = 1, /* Display symbol by itself */
dspl_cmnt = 2 /* Display symbol with comment */
}
wpt.attr := Ord(Package[7]);
{ The "attr"
member should be set to a value of 0x60.}
wpt.smbl := GetIntData(Package,8,2);
YY := GetCoordinate(Copy(Package,28,4));
XX := GetCoordinate(Copy(Package,32,4));
//WPt.AddPt(XX,YY);
dbf1.Append;
dbf1.FieldByName('id').AsInteger:=1;
dbf1.FieldByName('name').asstring:=wpt.Name;
dbf1.FieldByName('comment').AsString:=wpt.comment;
dbf1.FieldByName('wpt_class').AsInteger:=wpt.wpt_class;
dbf1.FieldByName('color').asinteger:=wpt.color;
dbf1.FieldByName('dspl').AsInteger:=wpt.dspl;
dbf1.FieldByName('alt').AsFloat:=wpt.Alt;
dbf1.FieldByName('dpth').AsFloat:=wpt.dpth;
dbf1.FieldByName('dist').AsFloat:=wpt.dist;
dbf1.FieldByName('attr').AsInteger:=wpt.attr;
dbf1.FieldByName('xx').asfloat:=xx;
dbf1.FieldByName('yy').asfloat:=yy;
dbf1.Post;
end;
//从报文中解析坐标
function TGarminGPSForm.GetCoordinate(Semicircle : string) :do
uble;
//4 char
begin
if semicircle='' then
result:=0
else
result := (Ord(SemiCircle[1]) + Ord(SemiCircle[2]) * Power(2,8) + Ord(SemiCircle[3]) * Power(2,16) + Ord(SemiCircle[4]) * Power(2,24)) * 180/Power(2,31);
end;
//根据字节计算出整数来
function TGarminGPSForm.GetIntData(strData: string;
nbegin
Pos, nLength: integer): integer;
var
I : integer;
begin
result := 0;
for I := 1 to nLengthdo
begin
result := result + Round(Ord(StrData[nbegin
Pos + (I - 1)]) * Power(2,8 * (I - 1)));
end;
end;
procedure TGarminGPSForm.SendACK(RecByte : Byte);
var
sPack : string;
begin
sPack := #16;
sPack := sPack + Chr(Pid_Ack_Byte);
sPack := sPack + #2;
sPack := sPack + Chr(RecByte);
sPack := sPack + #0#0#16#3;
CalcCheckSum(sPack);
comm1.WriteCommData(pchar(sPack),length(sPack));
end;
function TGarminGPSForm.CalcCheckSum(var sPack : string) : integer;
var
nCheckByte : Byte;
I : integer;
begin
try
nCheckByte := 0;
for I := 0 to Ord(sPack[3])do
begin
nCheckByte := nCheckByte + Ord(sPack[I + 2]);
end;
sPack[4 + Ord(sPack[3])] := Chr(256 - nCheckByte);
result := Ord(sPack[4 + Ord(sPack[2])]);
//#16->#16#16
FixPackage(sPack);
except
end;
end;
function TGarminGPSForm.FixPackage(var sPack : string) : integer;
//#16->#16#16
var
n:integer;
I : integer;
str1:string;
begin
try
n:=0;
str1:=sPack;
sPack:=#16;
for I := 2 to length(str1)-2do
begin
if str1=#16 then
begin
//若是#16,则先插入一个
sPack:=sPack+#16;
n:=n+1;
end;
sPack:=sPack+str1;
end;
sPack:=sPack+#16#3;
result := n;
except
end;
end;
function TGarminGPSForm.unFixPackage(var sPack : string) : integer;
//#16#16->#16
var
n:integer;
I : integer;
str1:string;
begin
try
n:=0;
str1:=sPack;
sPack:=#16;
for I := 2 to length(str1)-2do
begin
if (str1=#16) and (str1[i+1]=#16) then
begin
//若是连续两个#16,则放弃第一个
n:=n+1;
end
else
sPack:=sPack+str1;
end;
sPack:=sPack+#16#3;
result := n;
except
end;
end;
procedure TGarminGPSForm.openClick(Sender: TObject);
begin
comm1.StartComm;
end;
procedure TGarminGPSForm.closeClick(Sender: TObject);
begin
comm1.StopComm;
end;
procedure TGarminGPSForm.Button1Click(Sender: TObject);
var
i: integer;
cmd:string;
begin
cmd:=#16;
cmd:=cmd+chr(Pid_Command_Data);
cmd := cmd + #2;
cmd := cmd + Chr(Cmnd_Transfer_Wpt);
cmd := cmd + #0#0#16#3;
calcCheckSum(cmd);
showmsg('W:',cmd);
comm1.WriteCommData(pansichar(cmd),length(cmd));
end;
procedure TGarminGPSForm.Comm1ReceiveData(Sender: TObject;
Buffer: Pointer;
BufferLength: Word);
var
frambuf:string;
ppchar;
i: integer;
begin
frambuf:='';
// memo1.Lines.Append('正在接收串口数据...');
pp:=buffer;
for i:=1 to bufferlengthdo
begin
frambuf:=frambuf+pp^;
pp:=pp+1;
end;
unFixPackage(frambuf);
showmsg('R:<'+inttostr(bufferlength)+'-'+inttostr(length(frambuf))+'> ',frambuf);
showmsg('W:',frambuf[2]);
sendAck(ord(frambuf[2]));
if frambuf[2]=#35 then
begin
Translate_D108_Wpt_type(frambuf);
end;
end;
====================================
运行结果:
R:<64-64> 10233A0FF060120000000FFFFFFFFFFFFFFFFFFFFFFFF6718621BD20A2510CB71425159469515946920202020303133320000008B103
W:23
R:<64-64> 10233A0FF060120000000FFFFFFFFFFFFFFFFFFFFFFFF72FA611BA8E9A151E0677B425159469515946920202020303133330000005A103
W:23
R:<64-64> 10233A0FF060120000000FFFFFFFFFFFFFFFFFFFFFFFFB5D1611B8D3A151E02D684251594695159469202020203031333400000042103
W:23
R:<64-64> 10233A0FF060120000000FFFFFFFFFFFFFFFFFFFFFFFFEFAA611BE5C4A1510CB714251594695159469202020203031333500000099103
W:23
R:<64-64> 10233A0FF060120000000FFFFFFFFFFFFFFFFFFFFFFFF3888611BD1AEA1510CB71425159469515946920202020303133360000009B103
W:23
R:<63-63> 10233A0FF060120000000FFFFFFFFFFFFFFFFFFFFFFFF5560611B3C97A151408142515946951594692020202030313337000000BB103
W:23
R:<64-64> 10233A0FF060120000000FFFFFFFFFFFFFFFFFFFFFFFF862E611B387BA151D0ED904251594695159469202020203031333800000060103
W:23