win32 WaitCommEvent

网页:

https://msdn.microsoft.com/en-us/library/windows/desktop/aa363479(v=vs.85).aspx

函数作用:
一个特定的通信设备等待事件发生。
该函数监视的事件的集合 is contained in the event mask associated with the device handle.

BOOL WINAPI WaitCommEvent(
  _In_  HANDLE       hFile,
  _Out_ LPDWORD      lpEvtMask,
  _In_  LPOVERLAPPED lpOverlapped
);

参数:

hFile [in]

通信设备的句柄,使用 CreateFile 函数 返回的这个句柄.

lpEvtMask [out]

是一个指针变量
该变量表示发送的事件的类型。
如果有错误发生,这个值是0
否则是下面的值中的一个

Value Meaning
EV_BREAK 0x0040 输入线上检测到break
EV_CTS 0x0008 The CTS (clear-to-send) 信号管脚改变状态
EV_DSR 0x0010 The DSR (data-set-ready) 信号管脚改变状态
EV_ERR 0x0080 线路状态错误. 线路状态错误 包括 CE_FRAME, CE_OVERRUN, and CE_RXPARITY.
EV_RING 0x0100 振铃指示被检测到
EV_RLSD 0x0020 The RLSD (receive-line-signal-detect) signal changed state.
EV_RXCHAR 0x0001 接收到一个字节 并且放置到输入缓冲区
EV_RXFLAG 0x0002 The event character was received and placed in the input buffer. The event character is specified in the device’s DCB structure, which is applied to a serial port by using the SetCommState function.
EV_TXEMPTY 0x0004 发送缓冲区中的最后一个字符被发送出去了

lpOverlapped [in]

指向OVERLAPPED 结构体的指针
如果hFile 是用FILE_FLAG_OVERLAPPED标志打开的,这个结构体是必须的。
如果hFile 是FILE_FLAG_OVERLAPPED标志打开的,lpOverlapped参数 不能是NULL
它必须指向一个有效的OVERLAPPED结构体。
如果hFile 是是FILE_FLAG_OVERLAPPED标志打开的,但是lpOverlapped 是NULL。
函数不能够正确的汇报操作是否完成,事件是否发生。

如果hFile 是FILE_FLAG_OVERLAPPED标志打开的,lpOverlapped 不是NULL。
WaitCommEvent 的表现是一个叠加操作。
在这种情况下,OVERLAPPED结构体,必须要包含一个有CreateEvent函数创建的Event Object,该Event Object 需要是手动复位的。

如果hFile 不是由FILE_FLAG_OVERLAPPED打开的,WaitCommEvent 直到指定的其中的一个事件发生,或者是一个错误发生的时候,才会返回。

Return value

函数执行成功,返回非0
函数执行失败,返回0
To get extended error information, call GetLastError.

Remarks

The WaitCommEvent 函数 监控 一个特定通信资源的event事件集合。
使用SetCommMask设置通信资源的当前event mask
使用GetCommMask查询通信资源的当前event mask

如果叠加操作不能立即完成,函数返回FALSE
GetLastError 函数返回ERROR_IO_PENDING,表示操作在系统后台执行中。

这个时候,在WaitCommEvent函数返回之前,系统设置OVERLAPPED结构体中的hEvent成员变量为没有信号状态。
当指定的events中的一个或者一个错误发生的时候,设置OVERLAPPED结构体中的hEvent成员变量的状态为有信号状态

调用进程可以使用wait函数中的一个,来检测event object的状态,然后使用GetOverlappedResult函数,来确定
WaitCommEvent操作的结果。
GetOverlappedResult报告操作是失败还是成功。
lpEvtMask 参数指向的变量,表示发生的event

如果一个叠加的WaitCommEvent操作正在运行,进程使用SetCommMask函数去改变设备句柄的event mask 。
WaitCommEvent会立即返回。
lpEvtMask 指向的变量的值为0

例子:

For an example, see Monitoring Communications Events.
https://msdn.microsoft.com/en-us/library/windows/desktop/aa363424(v=vs.85).aspx

Monitoring Communications Events

// SerialTB.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"

#include <windows.h>
#include <tchar.h>
#include <assert.h>
#include <stdio.h>


void _tmain(int argc, _TCHAR* argv[])
{
    HANDLE hCom;
    OVERLAPPED o;
    BOOL fSuccess;
    DWORD dwEvtMask;
    BOOL bResult   = FALSE;
    DWORD dwBytesRead       = 0;

    hCom = CreateFile( TEXT("\\\\.\\COM6"),
        GENERIC_READ | GENERIC_WRITE,
        0,    // exclusive access 
        NULL, // default security attributes 
        OPEN_EXISTING,
        FILE_FLAG_OVERLAPPED,
        NULL 
        );

    if (hCom == INVALID_HANDLE_VALUE) 
    {
        // Handle the error. 
        printf("CreateFile failed with error %d.\n", GetLastError());
        return;
    }

    // Set the event mask. 

    fSuccess = SetCommMask(hCom, EV_CTS | EV_DSR|EV_RXCHAR);

    if (!fSuccess) 
    {
        // Handle the error. 
        printf("SetCommMask failed with error %d.\n", GetLastError());
        return;
    }

    // Create an event object for use by WaitCommEvent. 

    o.hEvent = CreateEvent(
        NULL,   // default security attributes 
        TRUE,   // manual-reset event 
        FALSE,  // not signaled 
        NULL    // no name
         );


    // Initialize the rest of the OVERLAPPED structure to zero.
    o.Internal = 0;
    o.InternalHigh = 0;
    o.Offset = 0;
    o.OffsetHigh = 0;

    assert(o.hEvent);

    if (WaitCommEvent(hCom, &dwEvtMask, &o)) 
    {
        if (dwEvtMask & EV_DSR) 
        {
             // To do.
        }

        if (dwEvtMask & EV_CTS) 
        {
            // To do. 
        }
    }
    else
    {
        DWORD dwRet = GetLastError();
        if( ERROR_IO_PENDING == dwRet)
        {
            printf("I/O is pending... dwEvtMask = 0x%x\n",dwEvtMask);

            // To do.
            bResult = GetOverlappedResult(hCom,
                                &o,
                                &dwBytesRead,
                                TRUE) ; // 阻塞  Block


            if(bResult){

                printf("GetOverlappedResult Success dwEvtMask = 0x%x\r\n",dwEvtMask);

            }else{

                printf("GetOverlappedResult Fail dwEvtMask = 0x%x\r\n",dwEvtMask);
            }

        }
        else{ 
            printf("Wait failed with error %d.\n", GetLastError());
        }
    }

    return ;
}

以上程序,使用vs2010 建立一个 win32 控制台程序。
用COM6连接 TC35 板子,然后给TC35 上电,
运行上面的程序,然后关掉TC35的电源,这个时候,在串口上会有一个电平的变动。
会接收到一个字符。

运行效果如下:
这里写图片描述

0x01表示 EV_RXCHAR

注意:SetCommMask 和 SetCommState 不一样

BOOL WINAPI SetCommMask(
  _In_ HANDLE hFile,
  _In_ DWORD  dwEvtMask
);

BOOL WINAPI SetCommState(
  _In_ HANDLE hFile,
  _In_ LPDCB  lpDCB
);

猜你喜欢

转载自blog.csdn.net/wowocpp/article/details/80568376