从串口 C++ 读取字节 Windows
Reading bytes from serial port C++ Windows
嘿,我正在尝试与连接到 windows 机器的 xbees 进行交互。我可以在 AT 模式下通过协调器写入终端设备,并且可以看到流到我的 XCTU 控制台的数据。但是,我无法理解如何读取传入的数据。
我目前使用的代码如下。本质上,唯一重要的部分是最后 5 行左右(特别是读取和写入文件行),但我将 post 所有这些只是为了彻底。如何读取通过 com 端口发送到 xbee 的数据?我发送的数据只是0x00-0x0F。
我想我误解了读取文件的功能。我假设我发送到 xbee 的位存储在一个缓冲区中,可以一次读取一个。那是对的吗?或者我是否需要写入整个字节而不是读取可用数据?如果我的思路令人困惑,我很抱歉,我对串行通信还很陌生。感谢任何帮助。
#include <cstdlib>
#include <windows.h>
#include <iostream>
using namespace std;
/*
*
*/
int main(int argc, char** argv) {
int n = 8; // Amount of Bytes to Read
HANDLE hSerial;
HANDLE hSerial2;
hSerial = CreateFile("COM3",GENERIC_WRITE,0,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);// dont need to GENERIC _ WRITE
hSerial2 = CreateFile("COM4",GENERIC_READ,0,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);// dont need to GENERIC _ WRITE
if(hSerial==INVALID_HANDLE_VALUE || hSerial2==INVALID_HANDLE_VALUE){
if(GetLastError()==ERROR_FILE_NOT_FOUND){
//serial port does not exist. Inform user.
cout << "Serial port error, does not exist" << endl;
}
//some other error occurred. Inform user.
cout << "Serial port probably in use" << endl;
}
DCB dcbSerialParams = {0};
dcbSerialParams.DCBlength=sizeof(dcbSerialParams);
if (!GetCommState(hSerial, &dcbSerialParams)) {
cout << "error getting state" << endl;
}
dcbSerialParams.BaudRate=CBR_9600;
dcbSerialParams.ByteSize=8;
dcbSerialParams.StopBits=ONESTOPBIT;
dcbSerialParams.Parity=NOPARITY;
if(!SetCommState(hSerial, &dcbSerialParams)){
cout << "error setting serial port state" << endl;
}
COMMTIMEOUTS timeouts = {0};
timeouts.ReadIntervalTimeout = 50;
timeouts.ReadTotalTimeoutConstant = 50;
timeouts.ReadTotalTimeoutMultiplier =10;
timeouts.WriteTotalTimeoutConstant = 50;
timeouts.WriteTotalTimeoutMultiplier = 10;
if (!SetCommTimeouts(hSerial, &timeouts)){
cout << "Error occurred" << endl;
}
DWORD dwBytesWritten = 0;
DWORD dwBytesRead = 0;
unsigned char oneChar;
for (int i=0; i<16; i++)
{
oneChar=0x00+i;
WriteFile(hSerial, (LPCVOID)&oneChar, 1, &dwBytesWritten, NULL);
ReadFile (hSerial2, &oneChar, 1, &dwBytesRead, NULL); // what I tried to do, just outputs white space
}
CloseHandle(hSerial);
return 0;
}
在您的声明中:
ReadFile (hSerial2, &oneChar, 1, &dwBytesRead, NULL);
您需要检查 dwBytesRead
的值,看看您是否真的读取了任何字节。也许在连接的一侧,您想要一个简单的程序每秒发送一个字节。另一方面,您想检查可用字节并在它们进入时转储它们。
您的程序中可能发生的情况是您在短时间内填充了出站串行缓冲区,没有等待足够长的时间来读回任何数据,然后退出循环并关闭串行端口,很可能在它完成发送排队的数据之前。例如,在您的 CloseHandle()
调用之前写,您可以添加:
COMSTAT stat;
if (ClearCommError(hCom, NULL, &stat))
{
printf("%u bytes in outbound queue\n", (unsigned int) stat.cbOutQue);
}
并查看您是否在发送完成之前关闭句柄。
嘿,我正在尝试与连接到 windows 机器的 xbees 进行交互。我可以在 AT 模式下通过协调器写入终端设备,并且可以看到流到我的 XCTU 控制台的数据。但是,我无法理解如何读取传入的数据。
我目前使用的代码如下。本质上,唯一重要的部分是最后 5 行左右(特别是读取和写入文件行),但我将 post 所有这些只是为了彻底。如何读取通过 com 端口发送到 xbee 的数据?我发送的数据只是0x00-0x0F。
我想我误解了读取文件的功能。我假设我发送到 xbee 的位存储在一个缓冲区中,可以一次读取一个。那是对的吗?或者我是否需要写入整个字节而不是读取可用数据?如果我的思路令人困惑,我很抱歉,我对串行通信还很陌生。感谢任何帮助。
#include <cstdlib>
#include <windows.h>
#include <iostream>
using namespace std;
/*
*
*/
int main(int argc, char** argv) {
int n = 8; // Amount of Bytes to Read
HANDLE hSerial;
HANDLE hSerial2;
hSerial = CreateFile("COM3",GENERIC_WRITE,0,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);// dont need to GENERIC _ WRITE
hSerial2 = CreateFile("COM4",GENERIC_READ,0,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);// dont need to GENERIC _ WRITE
if(hSerial==INVALID_HANDLE_VALUE || hSerial2==INVALID_HANDLE_VALUE){
if(GetLastError()==ERROR_FILE_NOT_FOUND){
//serial port does not exist. Inform user.
cout << "Serial port error, does not exist" << endl;
}
//some other error occurred. Inform user.
cout << "Serial port probably in use" << endl;
}
DCB dcbSerialParams = {0};
dcbSerialParams.DCBlength=sizeof(dcbSerialParams);
if (!GetCommState(hSerial, &dcbSerialParams)) {
cout << "error getting state" << endl;
}
dcbSerialParams.BaudRate=CBR_9600;
dcbSerialParams.ByteSize=8;
dcbSerialParams.StopBits=ONESTOPBIT;
dcbSerialParams.Parity=NOPARITY;
if(!SetCommState(hSerial, &dcbSerialParams)){
cout << "error setting serial port state" << endl;
}
COMMTIMEOUTS timeouts = {0};
timeouts.ReadIntervalTimeout = 50;
timeouts.ReadTotalTimeoutConstant = 50;
timeouts.ReadTotalTimeoutMultiplier =10;
timeouts.WriteTotalTimeoutConstant = 50;
timeouts.WriteTotalTimeoutMultiplier = 10;
if (!SetCommTimeouts(hSerial, &timeouts)){
cout << "Error occurred" << endl;
}
DWORD dwBytesWritten = 0;
DWORD dwBytesRead = 0;
unsigned char oneChar;
for (int i=0; i<16; i++)
{
oneChar=0x00+i;
WriteFile(hSerial, (LPCVOID)&oneChar, 1, &dwBytesWritten, NULL);
ReadFile (hSerial2, &oneChar, 1, &dwBytesRead, NULL); // what I tried to do, just outputs white space
}
CloseHandle(hSerial);
return 0;
}
在您的声明中:
ReadFile (hSerial2, &oneChar, 1, &dwBytesRead, NULL);
您需要检查 dwBytesRead
的值,看看您是否真的读取了任何字节。也许在连接的一侧,您想要一个简单的程序每秒发送一个字节。另一方面,您想检查可用字节并在它们进入时转储它们。
您的程序中可能发生的情况是您在短时间内填充了出站串行缓冲区,没有等待足够长的时间来读回任何数据,然后退出循环并关闭串行端口,很可能在它完成发送排队的数据之前。例如,在您的 CloseHandle()
调用之前写,您可以添加:
COMSTAT stat;
if (ClearCommError(hCom, NULL, &stat))
{
printf("%u bytes in outbound queue\n", (unsigned int) stat.cbOutQue);
}
并查看您是否在发送完成之前关闭句柄。