【问题标题】:Convert integer to a char buffer for serial communication...? [closed]将整数转换为字符缓冲区以进行串行通信......? [关闭]
【发布时间】:2015-08-24 16:56:10
【问题描述】:

我的结构如下

struct msg {  
uint16_t data1;
int data2;
}

我是把结构体数据转换成字符串(char buffer)后通过串口发送的。

我其实是在使用memcpy将内容复制到缓冲区中(使用PRAGMA进行结构打包)

我面临的问题是我的板子的 puts 功能,一旦遇到 NULL 字符就会停止(即如果 1 bye 为 0,则 ASCII 等效 o decimal 0 为 NULL)

如果 data2 = 12 那么 memcpy 之后的内存将为 00 00 00 0C (HEX)。一个 puts 看到它停止并返回的第一个 00。

我无法更改我的串行端口设置或 puts 功能。 将 int 转换为 char 缓冲区中的 4 字节而不任何字节为 0 的最佳方法是什么

【问题讨论】:

  • 您有三个选择。第一种是停止发送二进制数据,而是发送一个 ASCII 格式的数字。第二种是使用为二进制数据设计的函数,而不是puts。第三个是使用Base64之类的东西对整个字符串进行编码。
  • 您应该搜索“序列化”或“编组”。无论如何,您不应该只发送struct 的二进制图像。
  • "什么是在 char 缓冲区中将 int 转换为 4 字节而不任何字节为 0 的最佳方法" 那么使用转换为字符串。
  • 你确定访问串口的唯一方法是通过stdout吗?
  • Pidgeonhole 原则说你输了。

标签: c++ c arrays char int


【解决方案1】:

puts() 设计用于发送以空字符结尾的字符串。这不是用于发送二进制数据的正确函数:

  • 二进制数据不能保证为空终止,导致puts() 发送比需要更多的数据。
  • 二进制数据可能会嵌入 '\0' 字符,这会提前结束输出
  • 如果您的标准输出以文本模式打开,二进制数据可能会嵌入其他可能造成伤害的特殊字符,具体取决于您的系统/环境。

正确的解决方案取决于您用于微控制器的环境/编译器/库。串行 I/O(通过 UART/USART)通常有一些特殊功能。但是如果你被允许使用puts(),你当然可以使用putchar()来逐字节输出。

 msg m;  
 int sz = sizeof(m); 
 for (char*p=reinterpret_cast<char*>(&m); sz--; p++) 
     putchar(*p); 

如果您必须不惜一切代价使用puts(),一种方法是发送至convert the buffer in printable hex digits 并发送此字符串。十六进制数字将需要两倍的消息大小(+1 空终止符)。

【讨论】:

  • 或者您只需使用std::ostream write() 变体之一。
  • @πάνταῥεῖ 当然是的:这样会更有效率!但我知道他的 OP 在选择功能方面受到了某种限制。
  • 您对十六进制数字表示的想法非常巧妙。无论如何,OP应该澄清他们的实际通信协议。
猜你喜欢
  • 2013-12-22
  • 2014-07-13
  • 1970-01-01
  • 2022-11-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多