从串行端口接收的数据不正确,有时会更改!
if (WaitCommEvent(hSerial, &eventMask, NULL))
{
if (ReadFile(hSerial, &input, 14, &bytesRead, NULL) !=0)
{
for (int i = 0; i < sizeof(input); i++)
{
cout << hex <<(int)input[i]<<endl;
}
}
else
{
cout << "error reading filen";
}
}
else
{
cout << "error waiting for comm eventn";
}
数据是:
50
ffffffaf
0
e
2
42
2
b
d
0
1
1
50
ffffffe5
当我用Pyserial获得数据时,数据是:
50AF000E0242020B0D00010150E5
正如你所看到的,我得到了额外的"ffffff",错过了一些"0"!由于数据丢失,有时"af"变为"2f"!
我的代码有什么错误吗?
问题不在于数据,数据本身很好。是你打印的数据有问题。
您没有考虑到input
使用的是签名的char
类型,该类型在分配给签署的int
时得到符号扩展。这就是当打印值为0xAF
或0xE5
的char
时,ffffffaf
和ffffffe5
中额外的f
s的来源,因为它们的高位在这两种情况下都是1
,并被携带到扩展位中,例如:
0x50 = 01010000
0x00000050 = 00000000 00000000 00000000 01010000
<--------------------------^
0xAF = 10101111
0xFFFFFFAF = 11111111 11111111 11111111 10101111
<--------------------------^
0xE5 = 11100101
0xFFFFFFE5 = 11111111 11111111 11111111 11100101
<--------------------------^
另一方面,无符号值是零扩展:
0x50 = 01010000
0x00000050 = 00000000 00000000 00000000 01010000
<-------------------------|
0xAF = 10101111
0x000000AF = 00000000 00000000 00000000 10101111
<-------------------------|
0xE5 = 11100101
0x000000E5 = 00000000 00000000 00000000 11100101
<-------------------------|
您也没有考虑到,默认情况下,带有std::hex
的std::cout
将只使用1个十六进制数字打印数值0..15
,因此不会打印任何前导0
十六进制数字。e
、b
、d
是与0e
、0b
、0d
相同的数值。如果您想打印0
,您必须告诉std::cout
将值填充到至少2个十六进制数字。
试试这个:
char input[...];
...
if (ReadFile(hSerial, &input, 14, &bytesRead, NULL))
{
for (int i = 0; i < bytesRead; ++i)
{
cout << hex << setw(2) << setfill('0') << static_cast<int>(static_cast<unsigned char>(input[i])) << endl;
}
}
如果将input
更改为使用unsigned char
而不是char
,则可以删除一种类型的强制转换:
unsigned char input[...];
...
if (ReadFile(hSerial, &input, 14, &bytesRead, NULL))
{
for (int i = 0; i < bytesRead; ++i)
{
cout << hex << setw(2) << setfill('0') << static_cast<int>(input[i]) << endl;
}
}