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

时间:2016-07-12 13:19:12

标签: c serial-port c89

我正在编写C89代码,通过RS232将hex命令发送到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

为什么除了这个设备上的其中一个输入外,它还可以使用?

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

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

1 个答案:

答案 0 :(得分:1)

如果system_command的类型是char的数组,那么您的系统char上的已签名

编译器执行变量参数printf函数的参数的default argument promotion,将char转换为int。当发生这种情况时,它也会执行签名扩展

我建议的解决方案是使用显式uint8_t类型而不是普通charuint8_t类型是typedef的类型别名(unsigned char),如果您没有fixed-width integers from <stdint.h>,则可以使用该类别。

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

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