我是否通过 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
的数组,那么在您的系统上 char
是 signed.
编译器会对变量参数 printf
函数的参数进行 default argument promotion,这会将 char
转换为 int
。当发生这种情况时,它也会执行 sign extension.
我推荐的解决方案是使用显式 uint8_t
类型而不是普通 char
。 uint8_t
类型是 unsigned char
的类型别名(一个 typedef
),如果你没有 fixed-width integers from <stdint.h>
.
,你可以使用它
我还建议您停止使用字符串函数(如 sprintf
)来处理数据,您处理的不是字符串而是二进制数据。请记住,C 中的所有字符串都以等于零的特殊字符 '[=23=]'
结尾。现在,如果您使用字符串函数并且数据在中间某处包含一个零,您认为会发生什么?
要真正回答这个问题,如果您正确发送数据,那么答案是肯定的。数据发送正确,问题是你的数据呈现方式。
我正在编写 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
的数组,那么在您的系统上 char
是 signed.
编译器会对变量参数 printf
函数的参数进行 default argument promotion,这会将 char
转换为 int
。当发生这种情况时,它也会执行 sign extension.
我推荐的解决方案是使用显式 uint8_t
类型而不是普通 char
。 uint8_t
类型是 unsigned char
的类型别名(一个 typedef
),如果你没有 fixed-width integers from <stdint.h>
.
我还建议您停止使用字符串函数(如 sprintf
)来处理数据,您处理的不是字符串而是二进制数据。请记住,C 中的所有字符串都以等于零的特殊字符 '[=23=]'
结尾。现在,如果您使用字符串函数并且数据在中间某处包含一个零,您认为会发生什么?
要真正回答这个问题,如果您正确发送数据,那么答案是肯定的。数据发送正确,问题是你的数据呈现方式。