串列埠通訊-----串列埠監聽執行緒全域性函式(C++)
阿新 • • 發佈:2019-02-08
```````
#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(§ion);
//獲取對話方塊類的指標
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(§ion);
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( §ion );
}
}
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);
}