delphi – 如何增加分配给变量的串行数据的数量?
我已经下载并安装了comport库.我有一个模拟器通过串口RS232发送数据到Selphi程序.这是以下代码段.
procedure TMainForm.ComPortRxChar(Sender: TObject; Count: Integer); begin ComPort.ReadStr(CPort.Str,Count); Memo.Text := Memo.Text + CPort.Str; end; 至于CPort库部分,我补充说: var Str: String; here is the problem. 正在经历的数据示例大致相同 $HEHDT,288.45,T*1D $HEHDT,288.46,T*18 $HEHDT,288.47,T*1A 等等.每行每秒发送一次.因此,使用上面的代码,备忘录将显示所有这些数据. 但是,如果我将代码更改为: procedure TMainForm.ComPortRxChar(Sender: TObject; Count: Integer); begin ComPort.ReadStr(CPort.Str,Count); Memo.Text := Memo.Text + CPort.Str + 'haha'; end; 这是备忘录上的内容: $HEHDT,2haha88.45,T*haha1Dhaha $HEHDT,2haha88.46,T*haha18haha $HEHDT,2haha88.47,T*haha1Ahaha 8个ASCII字符后出现“haha”.这在CPort.pas中意味着什么呢? 我如何改变代码,使整个数据字符串,无论如何 更新**我意识到这部分CPort库包含以下代码.任何人都可以启发我如何编辑代码?或者它是否是我采购的正确块.谢谢! // split buffer in packets procedure TComDataPacket.HandleBuffer; procedure DiscardPacketToPos(Pos: Integer); var Str: string; begin FInPacket := True; if Pos > 1 then begin Str := Copy(Buffer,1,Pos - 1); // some discarded data Buffer := Copy(Buffer,Pos,Length(Buffer) - Pos + 1); DoDiscard(Str); end; end; procedure FormPacket(CutSize: Integer); var Str: string; begin Str := Copy(Buffer,CutSize); Buffer := Copy(Buffer,CutSize + 1,Length(Buffer) - CutSize); CheckIncludeStrings(Str); DoPacket(Str); end; procedure StartPacket; var Found: Integer; begin // check for custom start condition Found := -1; DoCustomStart(Buffer,Found); if Found > 0 then DiscardPacketToPos(Found); if Found = -1 then begin if Length(FStartString) > 0 then // start string valid begin Found := Pos(Upper(FStartString),Upper(Buffer)); if Found > 0 then DiscardPacketToPos(Found); end else FInPacket := True; end; end; procedure EndPacket; var Found,CutSize,Len: Integer; begin // check for custom stop condition Found := -1; DoCustomStop(Buffer,Found); if Found > 0 then begin // custom stop condition detected CutSize := Found; FInPacket := False; end else if Found = -1 then begin Len := Length(Buffer); if (FSize > 0) and (Len >= FSize) then begin // size stop condition detected FInPacket := False; CutSize := FSize; end else begin Len := Length(FStartString); Found := Pos(Upper(FStopString),Upper(Copy(Buffer,Len + 1,Length(Buffer) - Len))); if Found > 0 then begin // stop string stop condition detected CutSize := Found + Length(FStopString) + Len - 1; FInPacket := False; end; end; end; if not FInPacket then FormPacket(CutSize); // create packet end; 解决方法
完整错误检查的简约解决方案是:
更新: (假设接收到的字符串以CRLF组合结束,并且数据包长度不是常量.这是NMEA 0183数据包) var finalBuf: AnsiString; // Example packet: $HEHDT,10.17,T*28 + CRLF // This is a NMEA 0183 protocol (Marine and GPS standard) // Subset for reading the heading. // HDT Heading – True // 1 2 3 // | | | //$--HDT,x.x,T*hh //1) Heading Degrees,true //2) T = True //3) Checksum // HE stands for: Heading – North Seeking Gyro {- Checking packet and checksum,calculating heading } Function ParseAndCheckNMEA_HDT(const parseS: AnsiString; var heading: Double): Integer; // Example packet: $HEHDT,T*28 + CRLF var i,p,err: Integer; xorSum: Byte; xorStr: AnsiString; headingStr: AnsiString; begin Result := 0; // Assume ok if (Pos('$HEHDT',parseS) = 1) then // Start header ok ? begin p := Pos('*',parseS); if (p <> 0) and (Length(parseS) >= p + 2) then // Assumes a checksum in packet begin xorSum := Ord(parseS[2]); for i := 3 to p - 1 do // Calculate checksum xorSum := xorSum xor Ord(parseS[i]); xorStr := IntToHex(xorSum,2); if (UpperCase(xorStr) = Copy(parseS,p + 1,2)) then // Checksum ok ? begin // Validate heading headingStr := Copy(parseS,8,p - 10); Val(headingStr,heading,err); if (err <> 0) then Result := 4; // Not a valid float end else Result := 3; // Wrong checksum end else Result := 2; // No checksum end else Result := 1; // Wrong header end; procedure TMainForm.ComPortRxChar(Sender: TObject; Count: Integer); var i,err: Integer; strBuf: AnsiString; heading: Double; begin ComPort.ReadStr(CPort.Str,Count); strBuf := CPort.str; for i := 1 to Length(strBuf) do case strBuf[i] of '$' : finalBuf := '$'; // Start of package #10 : begin if (finalBuf <> '') and (finalBuf[1] = '$') then // Simple validate check begin SetLength( finalBuf,Length(finalBuf) - 1); // Strips CR err := ParseAndCheckNMEA_HDT(finalBuf,heading); if (err = 0) then Memo.Lines.Add(finalBuf); // Add validated string //else // Memo.Lines.Add('Error:' + IntToStr(err)); end; finalBuf := ''; end; else finalBuf := finalBuf + strBuf[i]; end; end; 知道开始字符和数据包结束,这应该是相当安全的使用. 更新2 要回答直接问题,为什么接收方法可以在数据字符串的中间添加“haha”字符串: comport例程按照自己的节奏传递一个或多个字符的数据.您无法控制何时获取数据或将有多少个字符.在我的回答中使用该方案,数据被缓冲,直到交付完整的包.通过TComPort的数据包支持,可以执行相同的操作. 从您的评论看,似乎有几个NMEA 0183传感器类型连接到串行端口. (给出其他长度的包,但都以$字符开头). 用以下函数替换ParseAndCheckNMEA_HDT以在这种情况下验证字符串: Function ParseAndCheckNMEA(const parseS: AnsiString): Integer; // Example packet: $HEHDT,p: Integer; xorSum: Byte; xorStr: AnsiString; begin Result := 0; // Assume ok if (Pos('$',2); if (UpperCase(xorStr) <> Copy(parseS,2)) then // Checksum ok ? Result := 3; // Wrong checksum end else Result := 2; // No checksum end else Result := 1; // Wrong header end; (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |