【MFC】SetCommMask()和WaitCommEvent()函数实现串口通信的接收

【MFC】串口通信接收模块底层函数API

前言

最近在做wince平台的上位机开发,关于串口通信都是直接调用系统底层的API函数,所以特地研究了一下串口通信的实现方法

正文

SetCommMask()函数

取得 串行端口事件信息,必须先设函数置信息掩码。简单来说,就是过滤条件。
SetCommMask()函数原型:

BOOL SetCommMask(HANDLE hFile, //标识通信端口的句柄
                 DWORD dwEvtMask //能够使能的通信事件
);
  • hFile:
    串行端口的Handle值,此值即为使用CreateFile函数后所返回的值。
  • dwEvtMask :
    信息掩码位值,由下列常组成,若没为0则取消所有的信息检测。
项目Value
EV_BREAK收到Break信号。
EV_CTSCTS(Clear To Send)线路发生变化。
EV_DSRDSR(Data Set Ready)线路发生变化。
EV_ERR线路状态错误,包括了CE_FRAME、CE_OVERRUN、CE_RXPARITY 3种错误。
EV_RING检测到响铃信号。
EV_RLSDCD(Carrier Detect)线路信号发生变化。
EV_RXCHAR输入缓冲区己收到一个字符。
EV_RXFLAG使用SetCommState函数设置的DCB结构中的等待字符己被传入榆入缓冲区。
EV_TXEMPTY在输出缓冲区中的数据己被完全送出。

举例:

SetCommMask(hComm, EV_RXCHAR | EV_CTS | EV_DSR);

WaitCommEvent()函数

使用SetCommMask函数设置所要检测的事件后,当此事件发生时,就可以用WaitCommEvent得知该事件是否已发生,若此函数返回True,表示设置的信息已发生。
函数原型:

BOOL WaitComrnEvent(
           HANDLE hFi1e,  //通信设备的句柄
           LPWORD lpEvtMask,//发生的事件变量的地址
           LPOVERLAPFED lpoverlapped //Overlapped结构的地址
)
  • hFile:
    串行端口的Handle值,此值即为使用CreateFile函数后所返回的值。
  • IpEvtMask:
    指向所检测到的信息的参数地址,32位长度,信息常数如SetCommMask函数的第二个参数,若发生错误,则此值返回0。
  • IpOverlapped:
    使用Overlapped方式打开文件时应给定的结构,在串行通信中若不采用后台工作时,则可不使用;但是在不使用Overlapped的情形下,若己设置了信息屏蔽,则会使得程序停在比函数上,一直到有事件发生,并被检到为止,才会离开等待的状态,因此使用时需注意,最好还是使用Overlapped结构在等待息的程序。

返回值:
  如果函数成功,返回非零值,否则返回0。要得到错误信息,可以调用GetLastError函数。

注意:
  如果hFile是用异步方式打开的,而lpOverlapped 指向一个非空的OVERLAPPED结构体,那么函数WaitCommEvent被默认为异步操作,马上返回。这时,OVERLAPPED结构体必须包含一个由CreateEvent()函数返回的手动重置事件对象的句柄hEven。
  如果hFile是用同步方式打开的,那么函数WaitCommEvent不会返回,直到要等待的事件发生。

程序举例:

网上关于wince下串口编程的方法大同小异,下面贴出接收线程部分代码。

// A code block
//串口读线程函数
DWORD CCESeries::ReadThreadFunc(LPVOID lparam)
{
    CCESeries *ceSeries = (CCESeries*)lparam;
    DWORD    evtMask;
 
    BYTE * readBuf = NULL;//读取的字节
    DWORD actualReadLen=0;//实际读取的字节数
    DWORD willReadLen;
    DWORD dwReadErrors;
    COMSTAT  cmState;

    // 清空缓冲,并检查串口是否打开。
    ASSERT(ceSeries->m_hComm !=INVALID_HANDLE_VALUE); 
    //清空串口
    PurgeComm(ceSeries->m_hComm, PURGE_RXCLEAR | PURGE_TXCLEAR );
    SetCommMask (ceSeries->m_hComm, EV_RXCHAR | EV_CTS | EV_DSR );
 
    while (TRUE)
    {   
        if (WaitCommEvent(ceSeries->m_hComm,&evtMask,0))
        {           
            SetCommMask (ceSeries->m_hComm, EV_RXCHAR | EV_CTS | EV_DSR );
            
            //表示串口收到字符     
            if (evtMask & EV_RXCHAR) 
            {
                ClearCommError(ceSeries->m_hComm,&dwReadErrors,&cmState);
                willReadLen = cmState.cbInQue ;
                if (willReadLen <= 0)
                {
                    continue;
                }

                readBuf = new BYTE[willReadLen];
 
                ZeroMemory(readBuf,willReadLen);
 
                //读取串口数据
                ReadFile(ceSeries->m_hComm, readBuf, willReadLen, &actualReadLen,0);
                //如果读取的数据大于,
                if (actualReadLen>0)
                {
                //触发读取回调函数
                    if (ceSeries->m_OnSeriesRead)
                    {
                        ceSeries->SeriesRead(ceSeries->m_pOwner,readBuf,actualReadLen);
                        actualReadLen = 0;
                    }
                }
                //释放内存
                delete[] readBuf;
                readBuf = NULL;
            }
        }
        //如果收到读线程退出信号,则退出线程
        if (WaitForSingleObject(ceSeries->m_hReadCloseEvent,500) == WAIT_OBJECT_0)
        {
            break;
        }
    }
    return 0;
}
 
//关闭读线程
void CCESeries::CloseReadThread()
{
    SetEvent(m_hReadCloseEvent);
    //设置所有事件无效无效
    SetCommMask(m_hComm, 0);
 
    //清空所有将要读的数据
    PurgeComm( m_hComm,  PURGE_RXCLEAR );
 
    //等待秒,如果读线程没有退出,则强制退出
    if (WaitForSingleObject(m_hReadThread,2000) == WAIT_TIMEOUT)
    {
        TerminateThread(m_hReadThread,0);
    }
    m_hReadThread = NULL;
}

参考链接

链接1: 串口开发中使用WaitCommEvent.

链接2: 串口编程C++实例(CE).

MFC(Microsoft Foundation Class)是一种用于编写Windows应用程序的库,它提供了许多可以简化开发过程的类和函数串口通信是一种用于在计算机和外部设备之间进行数据传输的通信方式,通过串口通信API可以实现MFC应用程序中与串口设备进行通信。 要在MFC应用程序中使用串口通信API,首先需要包含头文件"afxwin.h"和"afxdisp.h",然后创建一个CWinApp派生类的应用程序对象,并在InitInstance函数中调用AfxEnableControlContainer函数以启用ActiveX控件支持。接下来,创建一个对话框或窗口来实现用户界面,并在该对话框或窗口的消息映射中处理串口通信的逻辑。 使用串口通信API的实例涉及到打开、关闭串口、设置串口参数、读取和写入串口数据等操作。首先需要使用CreateFile函数打开串口,并通过DCB结构体设置串口的参数,包括波特率、数据位、停止位和校验位等。然后可以使用ReadFile和WriteFile函数来进行数据的读写操作。 在处理串口通信时,需要注意数据的接收和发送是异步进行的,需要通过事件或定时器来进行数据的处理和监控。可以使用WaitCommEvent函数等待串口事件的发生,并通过SetCommMask函数设置串口事件的掩码。此外,在使用串口通信API时还需要注意处理可能出现的错误和异常情况,例如串口设备被拔出、通信超时等。 总之,通过MFC串口通信API可以实现在Windows应用程序中与串口设备进行稳定而高效的通信,为实现串口通信功能提供了便利的工具和接口。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值