1. 程式人生 > >串列埠通訊-----串列埠監聽執行緒全域性函式(C++)

串列埠通訊-----串列埠監聽執行緒全域性函式(C++)

``````` #include "windows.h" #define COMMBUFFER_SIZE 18 //每組資料位元組數 //串列埠變數 HANDLE g_hComm = INVALID_HANDLE_VALUE;//串列埠控制代碼 HANDLE g_hCommThread = NULL;//執行緒控制代碼 OVERLAPPED m_overlappedRead; CString m_receive;//獲取串列埠資訊; //函式初始化時 BOOL CDetectionCarDoorDlg::OnInitDialog() { ````````` bool portStat = openPort(); if
(!portStat) { AfxMessageBox(L"串列埠初始化失敗!"); } //建立資料接收執行緒; g_hCommThread = CreateThread(NULL,0,ThreadCommRecvData,this,0,0); if (g_hCommThread == NULL) { MessageBox(L"掃碼槍資料接收執行緒建立失敗"); } } /////////////////////////////////////////// //串列埠監聽執行緒全域性函式 ////////////////////////////////////////// DWORD WINAPI ThreadCommRecvData( LPVOID lpParam ) { DWORD dwEvtMask = 0
; BOOL bResult = TRUE; int bytesComm = COMMBUFFER_SIZE;//傳送過來總的串列埠資料位元組數 DWORD bytesRead = 0;//當前接收資料位元組數 char commBuff[COMMBUFFER_SIZE];//串列埠資料儲存 DWORD dwError; COMSTAT comstat; DWORD Flag=0; OVERLAPPED ReadOver; memset(&ReadOver,0x00,sizeof(OVERLAPPED)); ReadOver.Internal=0
; ReadOver.InternalHigh=0; ReadOver.Offset=0; ReadOver.OffsetHigh=0; ReadOver.hEvent = CreateEventW(NULL,TRUE,FALSE,NULL); CRITICAL_SECTION section; InitializeCriticalSection(&section); //獲取對話方塊類的指標 CDetectionCarDoorDlg* pWnd = (CDetectionCarDoorDlg*)lpParam; while( g_bThreadRun ) { bResult = WaitCommEvent( g_hComm, &dwEvtMask, &ReadOver); if(!bResult) { switch( dwError = GetLastError() ) { case ERROR_IO_PENDING: Flag ^= 1; break; default: Flag=0; PurgeComm(g_hComm,PURGE_TXABORT | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_RXCLEAR); continue; } }else { bResult=ClearCommError(g_hComm,&dwError,&comstat); if(comstat.cbInQue==0) continue; } if( Flag & 1 ) { WaitForSingleObject(ReadOver.hEvent,INFINITE);///等待非同步操作完成 } Flag=0; GetCommMask( g_hComm,&dwEvtMask); if( ( dwEvtMask & EV_RXCHAR) == EV_RXCHAR ) { EnterCriticalSection(&section); memset(commBuff,0,COMMBUFFER_SIZE*sizeof(char) ); ClearCommError(g_hComm, &dwError, &comstat); if (comstat.cbInQue == 0) continue; bResult = ReadFile( g_hComm, // Handle to COMM port commBuff, // RX Buffer Pointer bytesComm, // Read bytes &bytesRead, // Stores number of bytes read &ReadOver); // pointer to the m_ov structure if( !bResult ) { switch( dwError = GetLastError() ) { case ERROR_IO_PENDING: Flag ^= 1; break; default: Flag=0; PurgeComm( g_hComm,PURGE_TXABORT | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_RXCLEAR ); continue; } } if(Flag & 1) { WaitForSingleObject( ReadOver.hEvent, INFINITE ); GetOverlappedResult( g_hComm,&ReadOver, &bytesRead,TRUE ); } //資料解析 pWnd->getData(commBuff, bytesRead); LeaveCriticalSection( &section ); } } return 0; } bool openPort() { `````````(建立串列埠控制代碼及設定各類引數,可參考https://blog.csdn.net/sazass/article/details/82259616) //設定事件 bool portStat = SetCommMask(g_hComm, EV_RXCHAR); if (!portStat) { AfxMessageBox(L"串列埠事件設定失敗"); return false; } ````````` } //把串列埠的char* 型別轉換成其他型別(CString) void getData(char* commBuff, int bytesRead) { int nDataFirstLength = 0; nDataFirstLength = bytesRead; memset(m_receive, 0, (COMMBUFFER_SIZE + 1)*sizeof(char)); memcpy(m_receive, commBuff, nDataFirstLength); CString strData; strData = CString(m_receive); //清除緩衝區 PurgeComm(g_hComm, PURGE_TXCLEAR | PURGE_RXCLEAR | PURGE_RXABORT | PURGE_TXABORT); }