该代码是MFC环境下的,(非MFC)可进行局部修改;
```````
#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);
}