C++串行端口数据接收不正确



从串行端口接收的数据不正确,有时会更改!

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时得到符号扩展。这就是当打印值为0xAF0xE5char时,ffffffafffffffe5中额外的fs的来源,因为它们的高位在这两种情况下都是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::hexstd::cout将只使用1个十六进制数字打印数值0..15,因此不会打印任何前导0十六进制数字。ebd是与0e0b0d相同的数值。如果您想打印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;
}
}

最新更新