加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

delphi – 如何增加分配给变量的串行数据的数量?

发布时间:2020-12-15 04:13:19 所属栏目:大数据 来源:网络整理
导读:我已经下载并安装了comport库.我有一个模拟器通过串口RS232发送数据到Selphi程序.这是以下代码段. procedure TMainForm.ComPortRxChar(Sender: TObject; Count: Integer);begin ComPort.ReadStr(CPort.Str,Count); Memo.Text := Memo.Text + CPort.Str;end;
我已经下载并安装了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中意味着什么呢?
库,在异步/同步部分下,最多只有8ASCII字符
分配给变量Str?

我如何改变代码,使整个数据字符串,无论如何
它的大小,将分配给变量Str而不是仅8个字节.

更新**我意识到这部分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;

知道开始字符和数据包结束,这应该是相当安全的使用.
标记包结束的#13和#10(CR LF)字符被剥离,并检查包的有效校验和,并计算得到的标题值.
然后将经过验证的字符串添加到备忘录中.

更新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;

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读