我是否通过 C 程序通过串口正确发送十六进制命令

Am I Properly Sending Hex Commands Over Serial Via C Program

我正在编写 C89 代码以通过 RS232 将十六进制命令发送到 HDMI Monoprice 4x2 矩阵开关。我编写的代码可以很好地控制 HDMI 端口 2-4,但不会切换到端口 1。我对所有 4 个 HDMI 端口都有相同的代码(每个端口都有适当的控制代码)。

sprintf(system_command, "%c%c%c%c", 0x00, 0xFF, 0xD5, 0x7B); // prepare HDMI1

然后我记录每个字节应该在这个数组中的内容:

    LOG_1("after we prep command system_command (x)1 - %02x", system_command[0]);
    LOG_1("after we prep command system_command (x)2 - %02x", system_command[1]);
    LOG_1("after we prep command system_command (x)3 - %02x", system_command[2]);
    LOG_1("after we prep command system_command (x)4 - %02x", system_command[3]);

结果如下,请注意字节 2 和 3 的较长值:

after we prep command system_command (x)1 - 01
after we prep command system_command (x)2 - fffffffe
after we prep command system_command (x)3 - ffffffd5
after we prep command system_command (x)4 - 7b

奇怪的是,我用正确的 HDMI2、3 和 4 值得到了这些相同的结果;切换输入没有问题。

sprintf(system_command, "%c%c%c%c", 0x01, 0xFE, 0xD5, 0x7B);
after we prep command system_command (x)1 - 01
after we prep command system_command (x)2 - fffffffe
after we prep command system_command (x)3 - ffffffd5
after we prep command system_command (x)4 - 7b

为什么此设备上除了一个输入之外的所有输入都能正常工作?

此外,我是否正确填充和读取了这些十六进制字节?

我还要补充一点,这个程序适用于多个其他设备。

如果 system_command 的类型是 char 的数组,那么在您的系统上 charsigned.

编译器会对变量参数 printf 函数的参数进行 default argument promotion,这会将 char 转换为 int。当发生这种情况时,它也会执行 sign extension.

我推荐的解决方案是使用显式 uint8_t 类型而不是普通 charuint8_t 类型是 unsigned char 的类型别名(一个 typedef),如果你没有 fixed-width integers from <stdint.h>.

,你可以使用它

我还建议您停止使用字符串函数(如 sprintf)来处理数据,您处理的不是字符串而是二进制数据。请记住,C 中的所有字符串都以等于零的特殊字符 '[=23=]' 结尾。现在,如果您使用字符串函数并且数据在中间某处包含一个零,您认为会发生什么?


要真正回答这个问题,如果您正确发送数据,那么答案是肯定的。数据发送正确,问题是你的数据呈现方式。