我正在尝试使用示例演示程序从 GPS 获取 NMEA 数据。我将 Delphi 与Aysnc Pro - 版本 5 ( TApdComPort
)组件一起使用。我使用OnTriggerAvail
事件来捕获 NMEA 字符串。我发现 GPS 单元正在提供不同的数据计数。大多数情况下,它一次提供一个 ASCII 字符。我使用缓冲区字符串捕获所有数据,然后填充所需的 NMEA 语句。在我的演示程序中一切正常。
但是问题出在我将演示代码集成到我的主应用程序中时。我认为我的主程序在接收单个 ASCII 字符时处理得不好。我注意到在调试时,如果接收数据计数(Count
from OnTriggerEvent
)超过 100,则可以填充数据。但是接收数据计数为 1(这种情况更有可能)不会被填充。
请在这里帮助我:
- 当数据以单个 ASCII 字符连续出现时,有没有更好的方法从串行端口接收数据?
- 为什么我的演示程序可以完美运行,但不能在我的主应用程序上运行?
这是我的演示代码
procedure TFormMain.btnOpenClick(Sender: TObject);
begin
Serial_init;
try
bufferString := '';
CarrierOn := false;
ApdComPort1.Open := True;
Memo1.Lines.Add('COM port ', IntToStr(ApdComPort1.ComNumber), ' is open');
except
on e : EInOutError do
Memo1.Lines.Add ('Error: ' + e.Message);
end;
end;
procedure TFormMain.Serial_init;
begin
ApdComPort1.ComNumber := 4;
ApdComPort1.Baud := 4800;
ApdComPort1.DataBits := 8;
ApdComPort1.Parity := pNone;
ApdComPort1.StopBits := 1;
end;
const
NMEA_START = '$';
NMEA_END_CF = #13;
NMEA_END_LF = #10;
procedure TFormMain.ApdComPort1TriggerAvail(CP: TObject; Count: Word);
var
sError : string;
c: ansichar;
i: integer;
CarrierOn: Boolean;
begin
for i := 1 to Count do
begin
c := ApdComPort1.GetChar;
if c = NMEA_START then
CarrierOn := True;
if CarrierOn then // $ has been found collect the data
begin
if (c = NMEA_END_CF) then exit;
if (c = NMEA_END_LF) then
begin
sError := '';
if (PopulateData(bufferString, sError)) then
begin
ApdComPort1.FlushInBuffer;
CarrierOn := false;
bufferString := '';
exit;
end;
CarrierOn := false;
bufferString := '';
end
else
begin
bufferString := bufferString + c;
end;
end;
end;
end;
function TFormMain.PopulateData(const Sentence: string; out ErrorMessage: string): boolean;
begin
Result := SentenceDecoder('$GPGSV', Sentence);
if Result then
Memo1.Lines.Add('Data:' + Sentence); // Display received GSV data
end;
function TFormMain.SentenceDecoder(sentenceName, Sentence: string): boolean;
begin
Result := Pos(sentenceName, sentence) = 1;
end;
提前致谢