0

Im trying to send a command to a dev. board and then receive a reply

E.G

(me) set attrib=yes

(Dev. Board) O.K

or

(Dev. Board) E.R.R

But it doesn't bounce back anything ... not an O.K or an E.R.R

while the board is booting echo is on .. so if I send the commands while the board is booting it it will bounce back an 'set attrib=yes' and once booted an 'E.R.R' because you cant send commands while booting.

my best guess is that it isn't reading the reply in time or trying to read it too soon.

procedure TReaderProgrammer.Button2Click(Sender: TObject);
Var 
  Buffer: AnsiString; 
  RxData: string; 
  Count : integer;
begin
  if ComPort1.Connected then
  begin
    ComPort1.WriteStr(edtSendText.Text+#13);
    comport1.ReadStr(RxData,Count);
    Buffer := Buffer + Rxdata;
    memoRxData.Text := memoRxData.Text+Buffer+#13+#10;
  end;
end;
4

1 回答 1

3

这里有几个悬而未决的问题,所以我必须做出一些可能是错误的假设,但让我们看看。

我不知道您使用的是什么通信端口库,所以我假设它是 SourceForge 的 CPort 库。我自己从未使用过它,但我读过它可以识别 Unicode,因此您可以使用 unicodestring 参数调用 write 方法,该参数将在发送之前由库转换为 ansistring。同样,当从外部世界接收 ansistring 时,库将转换为 Read 方法的 unicodestring。

由于串行通信的异步特性,重要的是要了解,当您使用 write 方法发送内容时,该方法会立即返回,而库和操作系统以波特率定义的速度一次吐出一个字符。结果,您的第一个代码从未收到任何内容,因为您在外部设备甚至收到第一个字符之前就已经尝试从 comm 端口读取。很高兴看到您现在通过为(可能是库事件)OnRxChar 实现事件处理程序迈出了成功的第一步。

OnRxChar 可能会为每个字符(或几个字符)触发。您需要有一个在这些事件之间持续存在的缓冲区。事件处理程序中的本地变量(就像您现在拥有的并且在堆栈上分配的那样)不是持久的,每次事件处理程序退出时它都会丢失。您应该将 Buffer 变量声明为 TReaderProgrammer 的一个字段。我不知道您为什么将缓冲区定义为 AnsiString,但我建议您尝试使用字符串(参考上面关于 Unicode 意识的讨论)。

type
  TReaderProgrammer = class
    ..
    RxBuffer: string;
    ..
  end;

当您向外部设备发送新命令时,需要清除缓冲区,以便它准备好接收新数据作为对您的命令的响应。

编辑:或者,您可以在收到并处理完整响应后立即清除 RxBuffer。

到目前为止,TReaderProgrammer.ComPort1RxChar 应该如下所示:

procedure TReaderProgrammer.ComPort1RxChar(Sender: TObject; Count: Integer);
var
  RxData : string;
begin
  (Sender as TComPort).ReadStr(RxData,Count);
  RxBuffer := RxBuffer + Rxdata;
  ...
end;

我猜,事件处理程序的其余部分可能只是为了查看接收进度,因此仅此而已。

于 2014-11-15T20:03:40.510 回答