SetCommMask

SetCommMask  

用途:设置串口通信事件

  原型:BOOL SetCommMask(HANDLE hFile, //标识通信端口的句柄

  DWORD dwEvtMask //能够使能的通信事件

  );

  参数说明:-hFile:串口句柄

  -dwEvtMask:准备监视的串口事件掩码

  串口上可能发生的事件如下表所示:

  

事件描述
EV_BREAK A break was detected on input.
EV_CTS The CTS (clear-to-send) signal changed state.
EV_DSR The DSR(data-set-ready) signal changed state.
EV_ERR A line-status error occurred. Line-status errors are CE_FRAME, CE_OVERRUN, and CE_RXPARITY.
EV_RING A ring indicator was detected.
EV_RLSD The RLSD (receive-line-signal-detect) signal changed state.
EV_RXCHAR A character was received and placed in the input buffer.
EV_RXFLAG 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 The last character in the output buffer was sent.

参数含义:

  EV_BREAK:收到BREAK信号。

  EV_CTS:CTS(clear to send)线路发生变化。

  EV_DSR:DST(Data Set Ready)线路发生变化。

  EV_ERR:线路状态错误,包括了CE_FRAME / CE_OVERRUN / CE_RXPARITY 3种错误。

  EV_RING:检测到振铃信号。

  EV_RLSD:CD(Carrier Detect)线路信号发生变化。

  EV_RXCHAR:输入缓冲区中已收到数据,即接收到一个字节并放入输入缓冲区。

  EV_RXFLAG:使用SetCommState()函数设置的DCB结构中的等待字符已被传入输入缓冲区中。

  EV_TXEMPTY:输出缓冲区中的数据已被完全送出。

操作举例:SetCommMask(hComm,EV_RXCHAR|EV_TXEMPTY);

上面函数执行完毕后将监视串口中有无数据和发送缓冲区中的数据是否全部发送完毕。

WaitCommEvent()
用途:用来判断用SetCommMask()函数设置的串口通信事件是否已发生。
原型:BOOL WaitCommEvent(HANDLE hFile,
LPDWORD lpEvtMask,
LPOVERLAPPED lpOverlapped
);
参数说明:
-hFile:串口句柄
-lpEvtMask:函数执行完后如果检测到串口通信事件的话就将其写入该参数中。
-lpOverlapped:异步结构,用来保存异步操作结果。
操作举例:OVERLAPPED os;
DWORD dwMask,dwTrans,dwError=0,err;

memset(&os,0,sizeof(OVERLAPPED));
os.hEvent=CreateEvent(NULL,TRUE,FALSE,NULL);
if(!WaitCommEvent(hComm,&dwMask,&os)){
//如果异步操作不能立即完成的话,函数返回FALSE,并且调用GetLastError()函
//数分析错误原因后返回ERROR_IO_PENDING,指示异步操作正在后台进行.这种情
//况下,在函数返回之前系统设置OVERLAPPED结构中的事件为无信号状态,该函数
//等待用SetCommMask()函数设置的串口事件发生,共有9种事件可被监视:
//EV_BREAK,EV_CTS,EV_DSR,EV_ERR,EV_RING,EV_RLSD,EV_RXCHAR,
//EV_RXFLAG,EV_TXEMPTY;当其中一个事件发生或错误发生时,函数将
//OVERLAPPED结构中的事件置为有信号状态,并将事件掩码填充到dwMask参数中

if(GetLastError()==ERROR_IO_PENDING){
/**************************************************************/
/*在此等待异步操作结果,直到异步操作结束时才返回.实际上此时 */
/*WaitCommEvent()函数一直在等待串口监控的事件之一发生,当事件发*/
/*生时该函数将OVERLAPPED结构中的事件句柄置为有信号状态,此时 */
/*GetOverlappedResult()函数发现此事件有信号后马上返回,然后下面*/
/*的程序马上分析WaitCommEvent()函数等到的事件是被监视的串口事 */
/*件中的哪一个,然后执行相应的动作并发出相应消息. */
/**************************************************************/
GetOverlappedResult(hComm,&os,&dwTrans,true);
switch(dwMask){
case EV_RXCHAR:
PostMessage(Parent,WM_COMM_RXCHAR,0,0);
break;
case EV_TXEMPTY:
PostMessage(Parent,WM_COMM_TXEMPTY,0,0);
break;
case EV_ERR:
switch(dwError){
case CE_FRAME:
err=0;
break;
case CE_OVERRUN:
err=1;
break;
case CE_RXPARITY:
err=2;
break;
default:break;
}
PostMessage(Parent,WM_COMM_ERR,(WPARAM)0,(LPARAM)err);
break;
case EV_BREAK:
PostMessage(Parent,WM_COMM_BREAK,0,0);
break;
case ...://其他用SetCommMask()函数设置的被监视的串口通信事件。
... ...
break;
default:break;
}
}

-以上简要介绍了大部分的串口通信api函数,笔者所写的串口通信软件用的是事件通知方式,该方式是
windows2000下效率较高的一种方式。而且只熟悉这些api函数也还是不够的,该机制下还要牵涉到多
线程和消息机制,其中读写串口的动作是由主线程来完成的,比如说操作者按下发送数据的按钮之后
,相应函数马上将某特定区域里面的数据发送出去,所以说用api函数写串口发送数据的功能是相对较
简单的。收数据的时候就要麻烦一点,在打开串口后首先主线程要设置要监视的串口通信事件,然后
将监视线程打开,用来监视主线程设置的这些串口通信事件是否已发生,当其中的某个事件发生后,
监视线程马上将该消息发送给主线程,其中监视线程在发送消息之前要确保主线程在收到消息后肯定
的知道串口究竟发生了什么样的事件,然后根据不同的事件类型进行处理。下面给出大致的主线程和
监视线程的大致工作流程:

主线程打开(其实就是主窗体打开之后)
|
|
V
打开串口(设置波特率、校验方式、数据位数、停止位数)
|
|
V
设置监视线程需要监视的串口通信事件
|
|
V
打开监视线程
|
|
V
等待各种事件的发生(比如发送数据单击事件,更改通信参数事件,监视线程发来的消息等)
--------------------------------------------------------------------------------
监视线程被打开
|
|
V
串口事件发生否(WaitCommEvent())(无论发生否均进入下面的代码)
|
|
V
异步操作是否正在后台进行?(if(GetLastError()==ERROR_IO_PENDING))
|
|
V
在此等待异步操作结果(GetOverlappedResult(hComm,&os,&dwTrans,true))
|
|
V
处理通信事件,根据事件类型的不同给主窗体发送不同的消息

总结起来说SetCommMask()和WaitCommEvent()是要成对使用的。在串口打开的时候SetCommMask,然后在读数据的线程中WaitCommEvent。不过要注意的是,一般不会在WaitCommEvent之后做关于该串口数据的处理(尤其是在数据比较多,处理缓慢的时候——容易丢失数据吧~~),一般会把数据简单的保存下来,再发送消息给一个专门的处理函数进行处理。

时间: 2024-10-08 20:50:29

SetCommMask的相关文章

c++ windows串口传输数据

用虚拟串口软件  测试 /////////////////////////////////////////////////////SerialPort.h//////////////////////////////////////////////////////// #include "SerialPort.h" HANDLE OpenSerialPort(string & strPort, ULONG ulBaudrate){ HANDLE hSerial; hSerial

使用win32 API 实现串行通信 (一)

本文基于wince平台,使用win32 API实现串行通信 1.打开和关闭串行端口 串行端口设备使用CreateFile函数打开,所使用的名称要遵循特定的格式,即3个字符 COM后紧跟要打开的COM端口号,再加个冒号,冒号是Windows CE所必需的. 如,hser=CreateFile(TEXT(“COM1:”),GENERIC_READ|GENERIC_WRITE,0, NULL,OPEN_EXISTING,0,NULL),为以可读可写的方式打开COM1端口. 调用CloseHandle函

英文不好也能快速"记忆" API

英文不好不要紧,把API函数导入打字练习类软件,即是练习打字速度,提高编程效率:也能短时间记忆API. 坚持每天打一遍,约2小时,连续打两周,会对API有很好的记忆,此方法是结合英文学习方法!以下是Window API函数例表,大家可以试试效果特别好! AbnormalTermination AbortDoc AbortPath AbortPrinter AbortProc AbortSystemShutdown AccessNtmsLibraryDoor ActivateKeyboardLay

DELPHI下API简述(1800个API)

DELPHI下API简述 http://zero.cnbct.org/show.asp?id=144 auxGetDevCaps API 获取附属设备容量 auxGetNumDevs API 返回附属设备数量 auxGetVolume API 获取当前卷设置 auxOutMessage API 向输出设备发送消息 auxSetVolume API 设置附属设备卷 AbortDoc API 终止一项打印作业 AbortPath API 终止或取消DC中的一切路径 AbortPrinter API

基于低压电量采集平台DW710C的基础开发

实验课题 (1)自定义通信规约,采用java或C++编写简单的PC端上位机软件,实现采集器与PC机的通信.实验可在DW710C-PC工程下进行. (2)实现LCD显示字符.数字.汉字和简单的图像,并能根据上位机发送的命令做相应的显示.此实验需要掌握LCD屏幕的显示原理(可参考LCD屏幕指导手册),并编写程序控制LCD显示(可参考工程DW710C-LCD):知道如何用字模提取软件提取字模:另外还要修改采集器端接收到的命令的解析程序,实现不同命令显示不同内容. 实验说明 采集器的一个485接口与RS

WinCE 驱动开发问题精华集锦

如何让系统加载自己写的驱动程序? 两种办法: 1.在[HKEY_LOCAL_MACHINE/Drivers/BuiltIn]下添加注册键. 2.在应用程序中调用ActivateDeviceEx. 在一些文件中用分号来表示注释,例如下面的内容 ; @CESYSGEN IF SERVERS_MODULES_HTTPD ; @CESYSGEN ENDIF 在“CESYSGEN...”前加了“@”,有没有什么特别的含义? 在WINCE的一些文件中,用“;”作为注释并在注释文字中用@CESYSGEN作为标

MFC--串口编程---WIN API的方式将串扣操作封装在线程类中

串口采集数据 本文档介绍的是如何获取串口原始数据并将原始数据解析成可处理或可展示的数据. 一.串口采集有很多方式: 1).MFC有一个专门的控件,直接编程采集,一个控件只能采集一个串口,而且串口名字比如是COM20可能就打不开(这里我没有实践,师兄给这样说的),波特率太高读数会出错. 2).利用Windows API通信函数(该工程里面就采用的这种方式) 3).利用Visual C++的标准通信函数_inp._inpw._inpd._outp等直接对串口进行操作. 4).第三方编写的通信类. 二

【转载】使用Win32API实现Windows下异步串口通讯

一,异步非阻塞串口通讯的优点 读写串行口时,既可以同步执行,也可以重叠(异步)执行.在同步执行时,函数直到操作完成后才返回.这意味着在同步执行时线程会被阻塞,从而导致效率下降.在重叠执行时,即使操作还未完成,调用的函数也会立即返回.费时的I/O操作在后台进行,这样线程就可以干别的事情.例如,线程可以在不同的句柄上同时执行I/O操作,甚至可以在同一句柄上同时进行读写操作."重叠"一词的含义就在于此. 二,异步非阻塞串口通讯的基本原理首先,确定要打开的串口名.波特率.奇偶校验方式.数据位.

NMEA 解析程序

经常需求使用 GPS 串口 NMEA 解析的功能,写了一段代码来完成引功能.分享一下,大家一起学习. 头文件: 1 #ifndef _GPS_MONITER_HH_ 2 #define _GPS_MONITER_HH_ 3 4 BOOL InitSerailPort(CString csSerialPort,LPVOID pParent = NULL); 5 DWORD WINAPI ReadNMEAThread(LPVOID lpParameter); 6 void SetSystemTime