我想做的是从一个COM端口获取 Dataframe ,每个 Dataframe 是258字节,并且以每秒8.5字节的速度不断进入。
我需要接收 Dataframe ,然后我将对它们进行一些其他处理,但现在我试图将它们打印到控制台。每个 Dataframe 以'/'
开头,以'?'
结尾。
下面是我写的代码(是的,我是一个新手):
#include <iostream>
#include <time.h>
#include <string>
#include "windows.h"
#pragma comment (lib, "OneCore.lib")
int main()
{
int portnum = 0;
ULONG ptNums[300];
ULONG some = 300;
ULONG ptsFound[20];
LPCSTR fName = "COM4";
ULONG status = GetCommPorts(ptNums, 100, ptsFound);
if (status == ERROR_SUCCESS) {
std::cout << "ports found:" << ptsFound[0] << "\n";
for (int i = 0; i < ptsFound[0]; i++) {
portnum = ptNums[i];
std::cout << "COM" << portnum << "\n";
}
}
HANDLE port = CreateFileA(fName, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0);
if (port == INVALID_HANDLE_VALUE) {
std::cout << "unable to open port\n";
}
DCB dcb;
dcb = { 0 };
//this is the default, use 8N1
dcb.DCBlength = sizeof(DCB);
dcb.fBinary = TRUE;
dcb.BaudRate = 250000;
dcb.fParity = FALSE;
dcb.ByteSize = 8;
dcb.Parity = NOPARITY;
dcb.StopBits = ONESTOPBIT;
DWORD eventMask;
SetCommState(port, &dcb);
SetCommMask(port,EV_TXEMPTY|EV_RXCHAR);
bool exitloop = false;
char arduBuf[258];
OVERLAPPED ov;
ov.Offset = 0;
ov.OffsetHigh = 0;
ov.hEvent = CreateEvent(0, TRUE, 0, 0);
SetupComm(port, 300, 300);
while (!exitloop) {
GetCommMask(port, &eventMask);
BOOL dataRet = WaitCommEvent(port, &eventMask, &ov);
DWORD dwait = WaitForSingleObject(ov.hEvent, INFINITE);
if (eventMask & EV_TXEMPTY) {
std::cout << "all data was sent\n";
exitloop = true;
}
if (dwait == WAIT_OBJECT_0) {
GetCommMask(port, &eventMask);
std::cout << "some random stuff was received\n";
BOOL status = ReadFile(port, arduBuf, sizeof(arduBuf), NULL, &ov);
std::cout << "status:" << status << "\nerror is:" << GetLastError() << "\n";
PurgeComm(port, PURGE_RXCLEAR);
if (status) {
std::cout << arduBuf << "\n";
}
ResetEvent(ov.hEvent);
//exitloop = true;
}
if (dwait == WAIT_TIMEOUT) {
std::cout << "timeout\n";
}
}
}
字符串
代码编译并运行,WaitForSingleObject()
返回WAIT_OBJECT_0
,但状态始终为0,GetLastError()
返回ERROR_IO_PENDING
。如果我打印出数据缓冲区,那么我可以看到我的数据,但它在一些混乱的行上,并且非常不一致:
x1c 0d1x的数据
我认为这是因为虽然EV_RXCHAR
得到了满足,但EV_TXEMPTY
永远不会得到满足。如果我将掩码设置为EV_TXEMPTY
,那么代码将在WaitForSingleObject()
处挂起。我认为这是因为在数据被读取之前,已经有新的数据填充了输入缓冲区。
我的问题:
- 这里明显有问题,有人能指出吗?
- 我不确定把阅读的过程放到
while
循环中是否是一个好主意,我知道应该把它放到一个线程中,一旦读失败或成功就终止,但是while
循环真的会导致问题吗? - 我在
WaitForSingleObject()
行上得到一个警告,ov.hEvent
可能是0。为什么会这样,这也是一个问题吗? - 我什么时候需要重置事件?
正如你可以告诉,我是新的COM端口I/O。我已经花了一天多的时间在这方面,并决定是时候问别人知道他们在做什么。
1条答案
按热度按时间ar7v8xwq1#
正如@tevemadar所说,
ERROR_IO_PENDING
不是一个失败;它表示读操作异步地等待完成。GetLastError
函数返回ERROR_IO_PENDING
,表示操作正在后台执行。当这种情况发生时,系统在WaitCommEvent
返回之前将OVERLAPPED
结构的hEvent成员设置为无信号状态,然后,当发生指定的事件或错误时,它将其设置为信号状态。使用
GetOverlappedResult
函数来确定WaitCommEvent
操作的结果可以获得一些更新。