【问题标题】:Receiving a HEX number and turning into an INT or STRING接收 HEX 数字并转换为 INT 或 STRING
【发布时间】:2020-10-23 10:16:59
【问题描述】:

我正在以 16 位(2 个字节)的形式从 ATmega 发送数据。我在 Delphi 中有一个接收数据的串行组件。

  • 如果我发送一个字符串(例如'FF'),我会将数据添加到我的备忘录组件中。一切都好。
  • 但是,如果我发送原始十六进制 $FF,我会收到一个接收数据闪烁提示“收到数据”,但没有任何内容添加到备忘录组件的行中。我不确定如何将此数据转换为整数或字符串,我可以使用。

一个解决方案会很好,但对 Delphi 如何看到StringChar 等的解释会很好。谢谢。

【问题讨论】:

  • 我想你的意思是 8 位字节?
  • 您应该显示用于接收数据的代码。我们需要知道接收缓冲区数据类型才能为您提供最佳答案。它是字节数组还是其他数据类型?我们还需要知道您使用的是哪个 Delphi 版本。旧的 Delphi(直到 Delphi 2007)使用 8 位字符,所有最近的(从 Delphi 2009 开始)使用 16 位字符 (Unicode),但也支持 AnsiChar(8 位字符)和 AnsiString 数据类型。

标签: delphi hex atmega delphi-6


【解决方案1】:

当您接收到数据时,您可以将它们转换为字节(如果需要)并转换为十六进制表示。

例如,如果你得到AnsiString:

  AnsiS := Comport.ReadAnsiString; //your reading here
  for i := 1 to Length(AnsiS) do
     Memo1.Lines.Add(IntToHex(Ord(AnsiS[i]), 2));

【讨论】:

  • 谢谢。这应该可行,但我对发送十六进制有另一个想法。我不能用这种方法发送数据分隔符。从 c 代码发送字符串可能是更好的选择。
【解决方案2】:

当您的 ATMega 发送字符串“FF”时,它会发送两个字符(“F”和“F”),每个字符都编码为其 ASCII 代码十进制 70。当您的 Delphi 程序收到这两个字节(d70 和 d70)时,它将这些 ASCII 代码转换为字符“F”和“F”并将它们添加到备忘录中。

当您的 ATMega 发送十六进制值 FF(在 Delphi 代码中表示为 $FF)时,它会发送一个十进制值为 255 的字节。当您的 Delphi 程序收到这个字节 (d255) 时,它会尝试将其转换为字符,但找不到此代码的可打印字符表示。因此,备忘录中没有添加任何内容。或者,也许您的接收代码正在过滤掉这个值以及可能的其他值。

目前尚不清楚您正在寻找哪种解决方案,但您可以使用 function IntToHex(Value: Integer; Digits: Integer): string;System.SysUtils.Format(const Format: string; const Args: array of const): string; 将字节值 (d255) 转换为十六进制或十进制表示形式,或者将其用作代码中的字节值。

【讨论】:

  • 感谢您的回复。我正在尝试解决这个通信问题,这就是我经过一番思考后得出的结论。一个 16 位的数字,例如 TCNT1 是 2 个字节。这是发送号码的最短方式。 Delphi 必须进行一些转换才能将数字转换为可用的格式。此方法只能发送 .hex 数字,因此无法发送其他字符作为数据分隔符。如果我把 TCNT1 变成一个字符串,我最终会发送 4 个字节。仍然很短,我现在可以在数字之间发送特殊的数据字符分隔符。在 c 中很容易将 2 字节的十六进制数转换为 4 字节的字符串。
  • Delphi 可以从串口读取任何类型的数据。 Delphi 程序的任务是以适当的方式正确解码和使用来自串行端口的数据。如果您要从 ATMega 发送二进制数据(例如 16 位计数器值),请不要将其转换为字符串,而是将其作为 2 个字节发送。接收时,不要尝试将接收到的字节提供给备忘录,而无需先转换为 2 个字节表示的值的十进制或十六进制表示。如果不需要在备忘录中显示 2 字节值,只需将其保存在 word 或整数变量中以备后用。
  • 如果您需要在数据包之间包含分隔符和/或其他标记,那么您需要考虑一些现有协议或创建自己的协议。
  • 同时,我正在使用 itoa 函数。但是,任何大于 32768 的整数都会返回从 65536 中减去的 -ve 数字。我有,char buffer[10]; char* itoa(unsigned int, char* , int);然后 itoa(60000, 缓冲区, 10);发送_str(缓冲区);我得到-5536。看起来 itoa 已签名。网络上说不应该。
猜你喜欢
  • 2017-07-20
  • 2023-01-13
  • 2016-03-23
  • 2011-06-02
  • 2010-11-22
  • 2019-06-13
  • 2018-02-28
  • 2020-04-15
  • 2020-03-01
相关资源
最近更新 更多