网页:
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
);