将整数转换为字符缓冲区以进行串行通信......? [关闭]

Posted

技术标签:

【中文标题】将整数转换为字符缓冲区以进行串行通信......? [关闭]【英文标题】: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 原则说你输了。 【参考方案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应该澄清他们的实际通信协议。

以上是关于将整数转换为字符缓冲区以进行串行通信......? [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

串行通信与并行通信

将字符串转换为 LPCWSTR 以用于 CreateFile() 以寻址串行端口

如何将无符号字符数组存储为浮点值?

C#开发串口通信实例及串口基础

将输入转换为字符串

Knex.js 和 MySQL:将整数转换为布尔值以进行批量选择