我是Windows上的串行库的新手,因此非常感谢任何指导。我有一个插入USB端口的微控制器,它不断通过UART发送数据。应该收到的示例是:
ADC值1:848 ADC值2:972 ADC中断计数:2300
(暂停)
ADC值1:849 ADC值2:971 ADC中断计数:2301
程序本身在GUI上具有一个线程,一旦用户选择了COM端口,便会创建一个文件名为 hCom 的文件。创建一个新线程,并将 hCom 传递给它。我试图在新线程上使用无限while循环来不断读取端口(稍后我将实现适当的检查条件)。 ReadFile函数一次读取一个字节,然后将它们打印到屏幕上。这不断循环。但是,在发送第一组(值1,值2,整数计数)之后,不再接收任何数据。
文件和线程生成的创建在这里:
HANDLE hCom = CreateFile(szComPort,
GENERIC_READ |
GENERIC_WRITE, // desired access should be read&write
0, // COM port must be opened in non-sharing mode
NULL, // don't care about the security
OPEN_EXISTING, // IMPORTANT: must use OPEN_EXISTING for a COM port
0, // usually overlapped but non-overlapped for existance test
NULL);
if (INVALID_HANDLE_VALUE == hCom) {
MessageBox(hwnd, "This port is not available or is in use.", "Error", MB_OK | MB_ICONERROR);
return WndProc(hwnd, WM_CREATE, wParam, lParam);
}
AppendText(hOut, "CONNECTED TO " + std::string(szComPort) + "\r\n");
DWORD myThreadID;
CreateThread(NULL, 0, serialHandler, &hCom, 0, &myThreadID);
return WndProc(hwnd, WM_CREATE, wParam, lParam);
这是我的线程处理程序:
DWORD WINAPI serialHandler(LPVOID lpParameter) {
HANDLE &hCom = *((HANDLE *) lpParameter);
SetCommState(hCom, &dcbSerialParams);
COMMTIMEOUTS tMyTimeOuts = {
MAXDWORD, // DWORD ReadIntervalTimeout;
0, // DWORD ReadTotalTimeoutMultiplier;
10000, // DWORD ReadTotalTimeoutConstant;
1000, // DWORD WriteTotalTimeoutMultiplier;
1000, // DWORD WriteTotalTimeoutConstant;
};
if (!SetCommTimeouts(hCom, &tMyTimeOuts))
printf("setting port time-outs.");
std::string sb = "";
DWORD dwEventMask, dwSize = 0;
while (1) {
char szBuf;
DWORD dwIncommingReadSize;
do {
int error = ReadFile(hCom, &szBuf, 1, &dwIncommingReadSize, NULL);
if (error !=0) {
if (dwIncommingReadSize > 0) {
dwSize += dwIncommingReadSize;
sb += szBuf;
printf("%c", szBuf);
sb = "";
}
} else {
printf("No Data Received - ");
DWORD lasterror = GetLastError();
lasterror = GetLastError();
}
} while (dwIncommingReadSize > 0);
}
return 0;
}
编辑:这是导致我遇到问题的WM_CREATE的一部分
hCom = CreateFile(szComPort,
GENERIC_READ | GENERIC_WRITE, // desired access should be read&write
0, // COM port must be opened in non-sharing mode
NULL, // don't care about the security
OPEN_EXISTING, // IMPORTANT: must use OPEN_EXISTING for a COM port
0, // usually overlapped but non-overlapped for existance test
NULL); // always NULL for a general purpose COM port
if (INVALID_HANDLE_VALUE == hCom) {
if ((ERROR_ACCESS_DENIED) == GetLastError()) { // then it exists and currently opened
wsprintf(szComPort, _T("&COM%d (in use)"), i);
AppendMenu(hSubMenu, MF_STRING, COM_PORT_MESSAGE_BASE + i, szComPort);
}
} else { // COM port exists
wsprintf(szComPort, _T("COM%d"), i);
AppendMenu(hSubMenu, MF_STRING, COM_PORT_MESSAGE_BASE + i, szComPort);
CloseHandle(hCom);
}
实际输出是:
ADC值1:848 ADC值2:972 ADC中断计数:2879 A没有收到数据-没有收到数据-没有收到数据-
以此类推。串行处理程序中的变量lasterror返回6,即ERROR_INVALID_HANDLE。我不确定为什么一组“读取”后句柄会从有效变为无效。
答案 0 :(得分:0)
我在代码的另一部分中打开了文件句柄,却忘记了将其关闭。当我尝试打开端口并且它不再存在时,这导致出现问题,并且我的readfile函数不起作用。确保检查所有createfile实例。
具体来说,我的代码无法正常工作的原因是双重的。首先,我将hCom的本地副本传递到另一个线程的堆栈上。
CreateThread(NULL, 0, serialHandler, &hCom, 0, &myThreadID);
然后,我返回了相同的功能以重新绘制GUI(我想更新菜单栏以显示已建立连接)。
return WndProc(hwnd, WM_CREATE, wParam, lParam);
内部WM_CREATE是端口扫描,它将重新打开所有端口以检查它们是否已打开。
hCom = CreateFile(szComPort,
GENERIC_READ | GENERIC_WRITE, // desired access should be read&write
0, // COM port must be opened in non-sharing mode
NULL, // don't care about the security
OPEN_EXISTING, // IMPORTANT: must use OPEN_EXISTING for a COM port
0, // usually overlapped but non-overlapped for existance test
NULL); // always NULL for a general purpose COM port
这干扰了先前的线程,因为它使用相同的句柄来收集数据。这就是为什么它会工作一会儿的原因,直到另一个线程运行并重新使用COM端口。我通过删除返回函数,将整数传递给新线程并在新线程中打开COM端口来解决此问题。