串口通讯-----串口监听线程全局函数(C++)

该代码是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(&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);
}
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值