串行通信 C++ ReadFile()
Serial Communication C++ ReadFile()
我创建了 2 个函数来通过串行端口进行读写,我使用 visual studio 2012、windows 7、64 位操作系统并使用 RS-232 串口线使用 c++ 进行编码。我连接的开发板应该在按下按钮时发送 5 个字符,TRG 1,代码有效,但输出值并不总是正确的。
char serialRead()
{
char input[5];
DCB dcBus;
HANDLE hSerial;
DWORD bytesRead, eventMask;
COMMTIMEOUTS timeouts;
hSerial = CreateFile (L"\\.\COM13", GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
if (hSerial == INVALID_HANDLE_VALUE)
{
cout << "error opening handle\n";
}
else
{
cout << "port opened\n";
}
dcBus.DCBlength = sizeof(dcBus);
if ((GetCommState(hSerial, &dcBus) == 0))
{
cout << "error getting comm state\n";
}
dcBus.BaudRate = CBR_9600;
dcBus.ByteSize = DATABITS_8;
dcBus.Parity = NOPARITY;
dcBus.StopBits = ONESTOPBIT;
if ((GetCommState(hSerial, &dcBus) == 0))
{
cout << "error setting comm state\n";
}
if ((GetCommTimeouts(hSerial, &timeouts) == 0))
{
cout << "error getting timeouts\n";
}
timeouts.ReadIntervalTimeout = 10;
timeouts.ReadTotalTimeoutMultiplier = 1;
timeouts.ReadTotalTimeoutConstant = 500;
timeouts.WriteTotalTimeoutMultiplier = 1;
timeouts.WriteTotalTimeoutConstant = 500;
if (SetCommTimeouts(hSerial, &timeouts) == 0)
{
cout << "error setting timeouts\n";
}
if (SetCommMask(hSerial, EV_RXCHAR) == 0)
{
cout << "error setting comm mask\n";
}
if (WaitCommEvent(hSerial, &eventMask, NULL))
{
if (ReadFile(hSerial, &input, 5, &bytesRead, NULL) !=0)
{
for (int i = 0; i < sizeof(input); i++)
{
cout << input[i];
}
cout << endl;
}
else
{
cout << "error reading file\n";
}
}
else
{
cout << "error waiting for comm event\n";
}
switch (input[4])
{
case '1' :
CloseHandle(hSerial);
return '1';
break;
case '2' :
CloseHandle(hSerial);
return '2';
break;
case '3' :
CloseHandle(hSerial);
return '3';
break;
case '4' :
CloseHandle(hSerial);
return '4';
break;
case '5':
CloseHandle(hSerial);
return '5';
break;
default :
CloseHandle(hSerial);
return '9';
break;
}
}
代码 运行 在端口配置正确并且数据正在传输的意义上是成功的。输出各不相同,大多数时候输出会打印整个 "TRG 1",但随机(似乎),输出将是 "TRG|}|}" 或 "T|}|}|}|}",即它将是string 和每个缺失的字符将被替换为“|}”而不是正确的字符。这是一个问题,因为我希望能够向它发送不同的触发器值和 运行 该变量的开关。
我是串行通信的新手,不是专业的程序员,所以我想知道发生了什么事?
串行通信不是基于数据包的。这些信息不会打包发送给您,在这种情况下,您必须一次性阅读整条消息;相反,它是一条流,因此您可以阅读半条消息、整条消息、多条消息等。
正如 zdan 在评论中所说,您需要检查从 ReadFile
读取的字节数,并使用它来组成 5 个字符的包,这是您的消息。
具体来说,只有前几个字符到返回的读取字节数是有效的;其他都是垃圾
我创建了 2 个函数来通过串行端口进行读写,我使用 visual studio 2012、windows 7、64 位操作系统并使用 RS-232 串口线使用 c++ 进行编码。我连接的开发板应该在按下按钮时发送 5 个字符,TRG 1,代码有效,但输出值并不总是正确的。
char serialRead()
{
char input[5];
DCB dcBus;
HANDLE hSerial;
DWORD bytesRead, eventMask;
COMMTIMEOUTS timeouts;
hSerial = CreateFile (L"\\.\COM13", GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
if (hSerial == INVALID_HANDLE_VALUE)
{
cout << "error opening handle\n";
}
else
{
cout << "port opened\n";
}
dcBus.DCBlength = sizeof(dcBus);
if ((GetCommState(hSerial, &dcBus) == 0))
{
cout << "error getting comm state\n";
}
dcBus.BaudRate = CBR_9600;
dcBus.ByteSize = DATABITS_8;
dcBus.Parity = NOPARITY;
dcBus.StopBits = ONESTOPBIT;
if ((GetCommState(hSerial, &dcBus) == 0))
{
cout << "error setting comm state\n";
}
if ((GetCommTimeouts(hSerial, &timeouts) == 0))
{
cout << "error getting timeouts\n";
}
timeouts.ReadIntervalTimeout = 10;
timeouts.ReadTotalTimeoutMultiplier = 1;
timeouts.ReadTotalTimeoutConstant = 500;
timeouts.WriteTotalTimeoutMultiplier = 1;
timeouts.WriteTotalTimeoutConstant = 500;
if (SetCommTimeouts(hSerial, &timeouts) == 0)
{
cout << "error setting timeouts\n";
}
if (SetCommMask(hSerial, EV_RXCHAR) == 0)
{
cout << "error setting comm mask\n";
}
if (WaitCommEvent(hSerial, &eventMask, NULL))
{
if (ReadFile(hSerial, &input, 5, &bytesRead, NULL) !=0)
{
for (int i = 0; i < sizeof(input); i++)
{
cout << input[i];
}
cout << endl;
}
else
{
cout << "error reading file\n";
}
}
else
{
cout << "error waiting for comm event\n";
}
switch (input[4])
{
case '1' :
CloseHandle(hSerial);
return '1';
break;
case '2' :
CloseHandle(hSerial);
return '2';
break;
case '3' :
CloseHandle(hSerial);
return '3';
break;
case '4' :
CloseHandle(hSerial);
return '4';
break;
case '5':
CloseHandle(hSerial);
return '5';
break;
default :
CloseHandle(hSerial);
return '9';
break;
}
}
代码 运行 在端口配置正确并且数据正在传输的意义上是成功的。输出各不相同,大多数时候输出会打印整个 "TRG 1",但随机(似乎),输出将是 "TRG|}|}" 或 "T|}|}|}|}",即它将是string 和每个缺失的字符将被替换为“|}”而不是正确的字符。这是一个问题,因为我希望能够向它发送不同的触发器值和 运行 该变量的开关。
我是串行通信的新手,不是专业的程序员,所以我想知道发生了什么事?
串行通信不是基于数据包的。这些信息不会打包发送给您,在这种情况下,您必须一次性阅读整条消息;相反,它是一条流,因此您可以阅读半条消息、整条消息、多条消息等。
正如 zdan 在评论中所说,您需要检查从 ReadFile
读取的字节数,并使用它来组成 5 个字符的包,这是您的消息。
具体来说,只有前几个字符到返回的读取字节数是有效的;其他都是垃圾