SetCommMask
用途:设置串口通信事件
原型:BOOL SetCommMask(
HANDLE hFile, //标识通信端口的句柄
DWORD dwEvtMask //能够使能的通信事件
);
参数说明:-hFile:串口句柄
-dwEvtMask:准备监视的串口事件掩码
串口上可能发生的事件如下表所示:
参数含义:
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:输入缓冲区中已收到数据,即接收到一个字节并放入输入缓冲区。 // ZC:我暂时 主要用这个参数
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:异步结构,用来保存异步操作结果。
在WIN32 API编程中,除了DCB结构之外,还需要了解COMMTIMEOUTS结构.这个结构是为了读写串口的超时而设置的.
COMMTIMEOUTS结构如下:
typedef struct _COMMTIMEOUTS {
DWORD ReadIntervalTimeout; //任意相邻 2 个字符之间的超时设置
DWORD ReadTotalTimeoutMultiplier; //读操作总的超时时间的系数
DWORD ReadTotalTimeoutConstant; //读操作总的超时时间的修正常量
DWORD WriteTotalTimeoutMultiplier; //写操作总的超时时间的系数
DWORD WriteTotalTimeoutConstant; //写操作总的超时时间的修正常量
} COMMTIMEOUTS,*LPCOMMTIMEOUTS;
ReadIntervalTimeout:两相邻字符之间最大的延时。当读串口数据时,一旦两个字符传输的时间间隔超过该时间,读函数将返回现有的数据。设置为0表示该参数不起作用。
ReadTotalTimeoutMultiplier:读操作总的超时事件的系数。 这个变量是不能单独使用的。 必须和ReadTotalTimeoutConstant 一起使用才有效果。
ReadTotalTimeoutConstant:读操作总的超时时间的修正常量。 这个变量也是不能单独使用的。必须和ReadTotalTimeoutMultiplier一起使用才有效果。
WriteTotalTimeoutMultiplier:写操作总的超时事件的系数。 这个变量是不能单独使用的。 必须和WriteTotalTimeoutConstant 一起使用才有效果。
WriteTotalTimeoutConstant:写操作总的超时时间的修正常量。 这个变量也是不能单独使用的。必须和WriteTotalTimeoutMultiplier一起使用才有效果。
在整个串口的读写操作中, 存在着两种超时设置。一种是间隔超时, 一种是总超时。 这两种超时是独立存在,互不影响的。
间隔超时, 只在读操作中存在。就是ReadIntervalTimeout。
当读操作中,前后两个字符之间的时间间隔超过时,读操作就结束了。举例来说,你一次读取8个字符,但是在你读取了第一个字符之后,在读取第二个字符时,间隔超时了,那么读操作就结束了, 这样整个操作就只读取了1个字节。 即使, 你的总时间没有超时。
另一种超时,就是总超时。 这里有一个公式。
总的读/写超时时间 = Read(Write)TotalTimeoutMultiplier x 要读/写的字节数
+ Read(Write)TotalTimeoutConstant.
这里要说明的一点,要读/写的字节数是从哪里来的:这个是从ReadFile 或者WriteFile 函数中定义的,是第三个参数所给定的。
在读操作时, 若当前所花读取时间已经超过了总的超时设置, 则读操作就结束了。即使, 每两个字符之间的间隔没有超时。 举例来说, 若总共读取8个字节。 间隔设置为8ms, 总超时系数为3ms,总超时常数为3ms。 则总的超时时间为3*8+3=27ms。若每个字符读取的间隔为7ms, 则这次操作总共能读取4个字符。 就结束了。因为读取第5个字符时, 已经需要35ms,
超过总超时时间了。
下面来讨论一下这几个参数的设定:
将ReadIntervalTimeout设置为MAXDWORD,将ReadTotalTimeoutMultiplier 和ReadTotalTimeoutConstant设置为0,表示读操作将立即返回存放在输入缓冲区的字符。
将ReadIntervalTimeout设置为MAXDWORD,将ReadTotalTimeoutMultiplier 和ReadTotalTimeoutConstant设置为MAXDWORD, 表示读操作会一直等待直到所需要读取的字节数全部接收到为止。 (大家可以把MAXDWORD 认为是永远)
将ReadIntervalTimeout设置为0, 则不使用间隔超时, 只考虑总超时设置。
3、
4、
5、