我正在编写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
为什么除了这个设备上的其中一个输入外,它还可以使用?
此外,我是否正确填充和读取这些十六进制字节?
我还要补充一点,这个程序适用于其他多个设备。
答案 0 :(得分:1)
如果system_command
的类型是char
的数组,那么您的系统char
上的已签名。
编译器执行变量参数printf
函数的参数的default argument promotion,将char
转换为int
。当发生这种情况时,它也会执行签名扩展。
我建议的解决方案是使用显式uint8_t
类型而不是普通char
。 uint8_t
类型是typedef
的类型别名(unsigned char
),如果您没有fixed-width integers from <stdint.h>
,则可以使用该类别。
我还建议您停止使用字符串函数(如sprintf
)来处理数据,不使用字符串而是使用二进制数据。请记住,C中的所有字符串都以特殊字符'\0'
终止,该字符等于零。现在,如果您使用字符串函数并且数据在中间某处包含零,您认为会发生什么?
要真正回答这个问题,如果您正确发送数据,那么答案是肯定的。数据发送正确,问题在于您的数据呈现。