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:输出缓冲区中的数据已被完全送出。
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的更多相关文章
- Serial Port Programming using Win32 API(转载)
In this tutorial we will learn How to communicate with an external device like a microcontroller boa ...
- 对比SerialCommunication和微软的SerialPort,向SerialPort看齐
SerialCommunication是我综合网上看到的代码稍作修改而成的串口通信类,而SerialPort则是C#的System类库的IO目录Ports子目录下的串口通信类.SerialCommun ...
- CE 操作串口
WinCE里面都是通过标准的系统API对串口进行操作的,但是串口不同于其它文件,它是是独占式地操作的. 下面是一个操作的串口类: #pragma once typedef void (*LPDataA ...
- C#封装好的Win32API
Kernel.cs using System; using System.Runtime.InteropServices; using System.Text; using HANDLE = Syst ...
- storysnail的Windows串口编程笔记
storysnail的Windows串口编程笔记 作者 He YiJun – storysnail<at>gmail.com 团队 ls 版权 转载请保留本声明! 本文档包含的原创代码根据 ...
- 英文不好也能快速"记忆" API
英文不好不要紧,把API函数导入打字练习类软件,即是练习打字速度,提高编程效率:也能短时间记忆API. 坚持每天打一遍,约2小时,连续打两周,会对API有很好的记忆,此方法是结合英文学习方法!以下是W ...
- [转]微软SerialPort秘籍[SerialPort为什么死锁程序的分析]
既然是秘籍,显然是写一些大家不常找到的,MSDN里遗漏提示大家注意的东西. 用过.net 2.0中,自带SerialPort的人,大多都遇到过.莫名其妙的执行Close的时候会死掉的问题.而Wince ...
- WinAPI你知道多少?!(上千个,好多都没见过)
http://www.cnblogs.com/vanver/archive/2013/06/13/NO-2013_06_13pm.html 播客开篇,讲讲废话:本篇播客只是推荐给热与钻研的同学们... ...
- DELPHI下API简述(1800个API)
DELPHI下API简述 http://zero.cnbct.org/show.asp?id=144 auxGetDevCaps API 获取附属设备容量 auxGetNumDevs API 返回附属 ...
随机推荐
- L1正则化和L2正则化
L1正则化可以产生稀疏权值矩阵,即产生一个稀疏模型,可以用于特征选择 L2正则化可以防止模型过拟合(overfitting):一定程度上,L1也可以防止过拟合 一.L1正则化 1.L1正则化 需注意, ...
- iOS 界面启动时,功能新特征显示
APP新启动的时候,都会有几张新的图片滑动,才能到主的界面.现在,我们新建一个控制器,专门来处理新特性,直接上代码. 第一步:新建一个NewfeatureController // // HWNewf ...
- Canvas标签基础
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- Fiddler过滤指定域名
Fiddler过滤指定域名的方法一 切换到fiddler右侧窗口的Filters选项卡,勾选顶部的“Use Filters”,找到Hosts区域,设置以下三个选项: 1.第一项有三个选项,不做更改: ...
- 谷歌浏览器使用IE内核
经常使用谷歌浏览器去到处溜达,可是,居然还不知道谷歌浏览的还有很多新鲜的设置,昨天遇到了调试一个脚本没有出现效果,而在IE中就可以显示所谓的效果: 查询了下,看到谷歌浏览器确实对脚本的部分样式要求还是 ...
- python3 字典的常用方法
字典的方法(可能需要重新整理) 函数 说明 D代表字典对象 D.clear() 清空字典 D.pop(key) 移除键,同时返回此键所对应的值 D.copy() 返回字典D的副本,只复制一层(浅拷 ...
- MySQL按中文拼音排序
好多时候,我们希望查询出来的记录能够按照汉语拼音即英文的26个字母排序,但是utf字符集是外国人弄的,不是按照汉语拼音的顺序排列的,因此,我们需要将要排序的字段把编码设定为GBK或者BG2312再进行 ...
- 20145105 《Java程序设计》实验四总结
实验四 Android开发基础 一.实验内容 基于Android Studio开发简单的Android应用并部署测试 了解Android组件.布局管理器的使用: 掌握Android中事件处理机制 二. ...
- 关于cp命令的编写
关于cp命令的编写 娄老师在课上详细的讲了命令who的编写过程~对此,我很有启发!于是想亲自动手试试~ 有什么不足的地方请大家提出来! Learning by doing ~ 做中学,真的只有自己动手 ...
- STM32.SPI(25Q16)
1.首先认识下W25Q16DVSIG, SOP8 SPI FLASH 16MBIT 2MB(4096个字节) (里面可以放字库,图片,也可以程序掉电不丢失数据放里面) 例程讲解: ① 1.用到SPI ...