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之后做关于该串口数据的处理(尤其是在数据比较多,处理缓慢的时候——容易丢失数据吧~~),一般会把数据简单的保存下来,再发送消息给一个专门的处理函数进行处理。

SetCommMask的更多相关文章

  1. Serial Port Programming using Win32 API(转载)

    In this tutorial we will learn How to communicate with an external device like a microcontroller boa ...

  2. 对比SerialCommunication和微软的SerialPort,向SerialPort看齐

    SerialCommunication是我综合网上看到的代码稍作修改而成的串口通信类,而SerialPort则是C#的System类库的IO目录Ports子目录下的串口通信类.SerialCommun ...

  3. CE 操作串口

    WinCE里面都是通过标准的系统API对串口进行操作的,但是串口不同于其它文件,它是是独占式地操作的. 下面是一个操作的串口类: #pragma once typedef void (*LPDataA ...

  4. C#封装好的Win32API

    Kernel.cs using System; using System.Runtime.InteropServices; using System.Text; using HANDLE = Syst ...

  5. storysnail的Windows串口编程笔记

    storysnail的Windows串口编程笔记 作者 He YiJun – storysnail<at>gmail.com 团队 ls 版权 转载请保留本声明! 本文档包含的原创代码根据 ...

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

    英文不好不要紧,把API函数导入打字练习类软件,即是练习打字速度,提高编程效率:也能短时间记忆API. 坚持每天打一遍,约2小时,连续打两周,会对API有很好的记忆,此方法是结合英文学习方法!以下是W ...

  7. [转]微软SerialPort秘籍[SerialPort为什么死锁程序的分析]

    既然是秘籍,显然是写一些大家不常找到的,MSDN里遗漏提示大家注意的东西. 用过.net 2.0中,自带SerialPort的人,大多都遇到过.莫名其妙的执行Close的时候会死掉的问题.而Wince ...

  8. WinAPI你知道多少?!(上千个,好多都没见过)

    http://www.cnblogs.com/vanver/archive/2013/06/13/NO-2013_06_13pm.html 播客开篇,讲讲废话:本篇播客只是推荐给热与钻研的同学们... ...

  9. DELPHI下API简述(1800个API)

    DELPHI下API简述 http://zero.cnbct.org/show.asp?id=144 auxGetDevCaps API 获取附属设备容量 auxGetNumDevs API 返回附属 ...

随机推荐

  1. 菜刀php过waf

    关于PHP 一.waf为啥会拦截菜刀.菜刀在连接时,会向server端POST数据,抓包查看: 会看到他向server端post了 @eval(base64_decode($_POST[z0]));  ...

  2. 机器学习理论基础学习3.1--- Linear classification 线性分类之感知机PLA(Percetron Learning Algorithm)

    一.感知机(Perception) 1.1 原理: 感知机是二分类的线性模型,其输入是实例的特征向量,输出的是事例的类别,分别是+1和-1,属于判别模型. 假设训练数据集是线性可分的,感知机学习的目标 ...

  3. Sublime text 3搭建Python-Anaconda开发环境

    网络上的教程各种各样,大同小异.自己安装时还是出了些问题,因此总结一篇博文. Sublime Text 是一款轻量级跨平台的文本编辑器,可通过包(Package)扩充自身功能. 有很多搭建python ...

  4. 016-sed

    行处理:一次处理一行.正则选定文本 ----->>sed处理格式:一.命令行格式:sed [options] 'command' files(如果没有则是通过管道)1.options: - ...

  5. VS2010/MFC编程入门之五十四(Ribbon界面开发:使用更多控件并为控件添加消息处理函数)

    上一节中鸡啄米讲了为Ribbon Bar添加控件的方法.本节教程鸡啄米将继续完善前面的实例,讲解一些稍复杂的控件的添加方法,及如何为它们添加消息处理函数. 一.为Ribbon Bar添加更多Ribbo ...

  6. uva10905

    /* 很好的字符串 比较方法 很多个字符串 组成的 数字 需要最大 然后 比较 a和b 是 比较a+b 和b+a 的大小 */ #include<cstdio> #include<s ...

  7. Java设计模式应用——模板方法模式

    所谓模板方法模式,就是在一组方法结构一致,只有部分逻辑不一样时,使用抽象类制作一个逻辑模板,具体是实现类仅仅实现特殊逻辑就行了.类似科举制度八股文,文章结构相同,仅仅具体语句有差异,我们只需要按照八股 ...

  8. iPhone手机获取uuid 安装测试app

    iPhone手机获取uuid 安装测试app UDID是一种iOS设备的特殊识别码.除序号之外,每台ios装置都另有一组独一无二的号码,我们就称之为识别码( Unique Device Identif ...

  9. 中国程序化购买广告解析:RTB/DSP/Ad Exchange/SSP/DMP,思维导图

    中国程序化购买广告解析:RTB/DSP/Ad Exchange/SSP/DMP 概念 程序化购买( Programmatic Buying):通过数字化.自动化.系统化的方式改造广告主.代理公司.媒体 ...

  10. 音响理论基础入门:Gain(增益)

    谈到放大器就必须先了解增益:一个小的信号Level(电平)经过放大电路成为大的信号Level ,也就是说由小变大之间的差异就叫增益,也叫放大率,反过来的叫衰减率.在音响系统内,一般以信号源的输入电平决 ...