Я новичок в последовательной библиотеке Windows, поэтому любые рекомендации очень ценятся. У меня есть микроконтроллер, подключенный к USB-порту, и он постоянно отправляет данные через UART. Пример того, что должно быть получено:
Значение АЦП 1: 848 Значение АЦП 2: 972 Количество прерываний АЦП: 2300
(пауза)
Значение АЦП 1: 849 Значение АЦП 2: 971 Количество прерываний АЦП: 2301
Сама программа имеет поток в графическом интерфейсе, и как только пользователь выбирает COM-порт, создается файл с именем дескриптора hCom . Создается новый поток, и ему передается hCom . Я пытался использовать бесконечный цикл while в новом потоке для постоянного чтения порта (позже я реализую соответствующие условия проверки). Функция ReadFile читает по одному байту за раз и выводит их на экран. Это непрерывно петли. Однако после отправки первого набора (val 1, val 2, int count) данные больше не принимаются.
Создание файла и потока spawn здесь:
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;
}
EDIT: вот часть 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);
}
Фактический результат:
АЦП значение 1: 848
АЦП значение 2: 972
Количество прерываний АЦП: 2879
ANo Данные получены - данные не получены - данные не получены -
И так далее. Переменная lasterror в serialhandler возвращает 6, которое равно ERROR_INVALID_HANDLE. Я не уверен, почему дескриптор переходит от действительного к недействительному после одного «набора» операций чтения.