我最终使用了来自开源TComPort包的TComPort和TComDataPacket。
串口设置:
object ComPort: TComPort
BaudRate = br4800
Port = 'COM1'
Parity.Bits = prNone
StopBits = sbTwoStopBits
DataBits = dbEight
Events = [evRxChar, evTxEmpty, evRxFlag, evRing, evBreak, evCTS, evDSR, evError, evRLSD, evRx80Full]
FlowControl.OutCTSFlow = False
FlowControl.OutDSRFlow = False
FlowControl.ControlDTR = dtrDisable
FlowControl.ControlRTS = rtsDisable
FlowControl.XonXoffOut = False
FlowControl.XonXoffIn = False
SyncMethod = smWindowSync
OnAfterOpen = ComPortAfterOpen
OnAfterClose = ComPortAfterClose
Left = 904
Top = 192
end
ComDataPacket设置:
object ComDataPacket: TComDataPacket
ComPort = ComPort
StartString = '$'
StopString = '*'
OnPacket = ComDataPacketPacket
Left = 808
Top = 240
end
使用的类型摘录
type
TMsgGP = (
msgGP,
msgGPGGA,
msgGPGLL,
msgGPGSV,
msgGPRMA,
msgGPRMC,
msgGPZDA
);
TSatellite = record
Identification: ShortInt;
Elevation: 0..90;
Azimut: Smallint;
SignLevel: Smallint;
end;
TSatellites = array[1..MAX_SATS] of TSatellite;
TGPSDatas = record
Latitude: Double;
Longitude: Double;
HeightAboveSea: Double;
Speed: Double;
UTCTime: TDateTime;
Valid: Boolean;
NbrSats: Shortint;
NbrSatsUsed: Shortint;
end;
ComDataPacketPacket事件处理程序:
procedure TForm1.ComDataPacketPacket(Sender: TObject; const Str: string);
var
Resultat: TStringList;
MsgCorrect, TypeMsg: string;
i: Integer;
begin
Resultat := TStringList.Create;
try
MsgCorrect := AnsiReplaceStr('$'+Str, ',,', ' , , ');
Resultat.Text := AnsiReplaceStr(LeftStr(MsgCorrect, Length(MsgCorrect) - 1), ',', #13#10);
TypeMsg := AnsiMidStr(Resultat[0], 4, 3);
case IndexMsgGP(TypeMsg) of
msgGPGGA:
begin
end;
msgGPGLL:
begin
end;
msgGPGSV:
begin
if Resultat.Count < 4 then
FGPSDatas.NbrSats := 0
else
FGPSDatas.NbrSats := StrToInteger(Resultat[3]);
if Resultat[2] = '1' then
begin
FSatRef := 0;
for i := 1 to 12 do
with FSatellites[i] do
begin
Identification := 0;
Elevation := 0;
Azimut := 0;
SignLevel := 0;
end;
end;
i := 4;
while (i + 4) <= (Resultat.Count) do
begin
with FSatellites[FSatRef + 1] do
begin
Identification := StrToInteger(Resultat[i]);
Elevation := StrToInteger(Resultat[i + 1]);
Azimut := StrToInteger(Resultat[i + 2]);
if Resultat[i + 3] <> '' then
SignLevel := StrToInteger(Resultat[i + 3])
else
SignLevel := 0;
end;
Inc(i, 4);
Inc(FSatRef);
end;
end;
msgGPRMA:
begin
end;
msgGPRMC:
begin
end;
msgGPZDA:
begin
end;
else
end;
finally
Resultat.Free;
end;
end;
NMEA处理在事件处理程序中进行。