[英]correctly reading or writing serial port Windows API
我已经阅读了很多串口读写问题。 到目前为止,没有人帮我弄清楚我的代码缺失了什么。 c ++的msdn示例有未定义的变量和缺少括号,所以虽然我可以添加括号但它仍然不起作用。 这就是我现在所拥有的。 看来我可以打开端口并进行配置,但我无法读取数据的字节/字符。 我真的只想要一个简单的异步串行读/写,以便程序从Arduino读取。
class MY_SERIAL
{
HANDLE serialinstance;
DWORD dwStoredFlags;
DWORD dwRes;
DWORD dwCommEvent;
OVERLAPPED osStatus = {0};
BOOL fWaitingOnStat;
//dwStoredFlags = EV_BREAK | EV_CTS | EV_DSR | EV_ERR | EV_RING | EV_RLSD | EV_RXCHAR | EV_RXFLAG | EV_TXEMPTY ;
DCB dcb;
COMMTIMEOUTS timeouts;
COMMCONFIG serialconfig;
public:
char inBuffer[1000];
char outBuffer[100];
PDWORD noBytes;
void close_serial()
{
CloseHandle(serialinstance);
}
//----------------------------------------------------
bool open_serial(LPCSTR portNumber) // serial port name use this format "\\\\.\\COM10"
{
serialinstance = CreateFile(portNumber, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
if(serialinstance == INVALID_HANDLE_VALUE)
{
int error = GetLastError();
printf("ERROR opening serial port %s\r\n", portNumber);
if(error == 0x2){printf("ERROR_FILE_NOT_FOUND\r\n");}
if(error == 0x5){printf("ERROR_ACCESS_DENIED\r\n");}
if(error == 0xC){printf("ERROR_INVALID_ACCESS\r\n");}
if(error == 0x6){printf("ERROR_INVALID_HANDLE\r\n");}
printf("error code %d\r\n", error);
return false;
}
if(GetCommState(serialinstance, &dcb)!= true)
{
printf("ERROR getting current state of COM %d \r\n", GetLastError());
return false;
}
else{printf("debug read current comstate\r\n");}
FillMemory(&dcb, sizeof(dcb), 0); //zero initialize the structure
dcb.DCBlength = sizeof(dcb); //fill in length
dcb.BaudRate = CBR_115200; // baud rate
dcb.ByteSize = 8; // data size, xmit and rcv
dcb.Parity = NOPARITY; // parity bit
dcb.StopBits = ONESTOPBIT;
if(SetCommState(serialinstance, &dcb) != true)
{
printf("ERROR setting new state of COM %d \r\n", GetLastError());
return false;
}
else{printf("debug set new comstate\r\n");}
/*
if (!BuildCommDCB("115200,n,8,1", &dcb)) //fills in basic async details
{
printf("ERROR getting port comstate\r\n");
return FALSE;
}
*/
if (!SetCommMask(serialinstance, EV_RXCHAR))
{
printf("ERROR setting new COM MASK %d \r\n", GetLastError());
return false;
}
else{printf("debug commmask set\r\n");}
timeouts.ReadIntervalTimeout = MAXDWORD;
timeouts.ReadTotalTimeoutMultiplier = 20;
timeouts.ReadTotalTimeoutConstant = 0;
timeouts.WriteTotalTimeoutMultiplier = 0;
timeouts.WriteTotalTimeoutConstant = 0;
if (!SetCommTimeouts(serialinstance, &timeouts))
{
printf("ERROR setting timeout parameters\r\n");
return false;
}
else{printf("debug timeouts set\r\n");}
osStatus.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
if (osStatus.hEvent == NULL)
{// error creating event; abort
printf("ERROR creating Serial EVENT\r\n");
return false;
}
else{printf("debug event created set\r\n");}
osStatus.Internal = 0;
osStatus.InternalHigh = 0;
osStatus.Offset = 0;
osStatus.OffsetHigh = 0;
assert(osStatus.hEvent);
printf("debug com port setting complete\r\n");
return true;
}
//---------------------------------------------------------
bool read_serial_simple()
{
char m[1000];
LPDWORD bytesRead;
if (WaitCommEvent(serialinstance, &dwCommEvent, &osStatus))
{
if(dwCommEvent & EV_RXCHAR)
{
ReadFile(serialinstance, &m, 1, bytesRead, &osStatus);
printf("data read = %d, number bytes read = %d \r\n", m, bytesRead);
return true;
}
else
{
int error = GetLastError();
if(error == ERROR_IO_PENDING){printf(" waiting on incomplete IO\r\n");}
else{printf("ERROR %d\r\n", error);}
return false;
}
}
return false;
}
};
所以我删除了读取功能。 我现在得到一个char,它报告读取1个字节,但char的值不正确。 我得到一系列48,13,10,偶尔为该字节的50值。 然而,Arduino正在发送一个0系列,然后是TerraTerm验证的128系列。 我还需要什么呢?
bool read_serial_simple()
{
unsigned char m = 0;
DWORD bytesRead;
if(ReadFile(serialinstance, &m, 1, &bytesRead, &osStatus) == true)
{
printf("data read = %d, number bytes read = %d \r\n", m, bytesRead);
return true;
}
else{
int error = GetLastError();
if(error == ERROR_IO_PENDING){printf(" waiting on incomplete IO\r\n");}
else{printf("ERROR %d\r\n", error);}
return false;
}
}
所以现在我可以读取一个字节的数据,但我不能写一个字节或更多的字节到端口。 我刚收到ERROR_IO_PENDING。 也有人可以帮忙解决这个问题。 写下我班级的功能。
bool write(DWORD noBytesToWrite)
{
if(WriteFile(serialinstance, outBuffer, noBytesToWrite, NULL, &osStatus) == true)
{
printf("message sent\r\n");
return true;
}
else
{
int error = GetLastError();
if(error != ERROR_IO_PENDING){LastError();}
return false;
}
}
我正在调用main中的两个函数,如下所示
myserial.open_serial(COM12);
myserial.outBuffer[0] = 'H';
myserial.outBuffer[1] = 'e';
myserial.outBuffer[2] = 'L';
myserial.outBuffer[3] = 'l';
myserial.outBuffer[4] = 'O';
for(int n=0; n<5; n++){printf("%c", myserial.outBuffer[n]);}
printf("\r\n");
while(1)
{
myserial.read();
myserial.write(5);
//system("PAUSE");
}
目前,arduino设置为读入字节并重复它们返回到pc。 它在arduino IDE串行监视器上做得很好,所以现在我只需要让这个pc程序写出来。
您的bytesRead
变量是一个未初始化的指针。 您正在将无效地址传递给ReadFile()
以进行写入。
将LPDWORD bytesRead
替换为DWORD bytesRead
,然后使用&bytesRead
将其传递给ReadFile()
。
编辑:还消除FILE_FLAG_OVERLAPPED
。 您没有正确处理它,如果您在阅读之前使用WaitForSingleObject()
,则没有必要使用它。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.