一、 COMMTIMEOUTS
COMMTIMEOUTS:COMMTIMEOUTS主要用于串口超时参数设置。COMMTIMEOUTS结构如下:
typedef struct _COMMTIMEOUTS {
DWORD ReadIntervalTimeout;
DWORD ReadTotalTimeoutMultiplier;
DWORD ReadTotalTimeoutConstant;
DWORD WriteTotalTimeoutMultiplier;
DWORD WriteTotalTimeoutConstant;
} COMMTIMEOUTS,*LPCOMMTIMEOUTS;
ReadIntervalTimeout:两字符之间最大的延时,当读取串口数据时,一旦两个字符传输的时间差超过该时间,读取函数将返回现有的数据。设置为0表示该参数不起作用。
ReadTotalTimeoutMultiplier:读取每字符间的超时。
ReadTotalTimeoutConstant:一次读取串口数据的固定超时。所以在一次读取串口的操作中,其超时为ReadTotalTimeoutMultiplier乘以读取的字节数再加上 ReadTotalTimeoutConstant。将ReadIntervalTimeout设置为MAXDWORD,并将ReadTotalTimeoutMultiplier 和ReadTotalTimeoutConstant设置为0,表示读取操作将立即返回存放在输入缓冲区的字符。
WriteTotalTimeoutMultiplier:写入每字符间的超时。
WriteTotalTimeoutConstant:一次写入串口数据的固定超时。所以在一次写入串口的操作中,其超时为WriteTotalTimeoutMultiplier乘以写入的字节数再加上 WriteTotalTimeoutConstant。
一般都会做以下设置:
TimeOuts.ReadIntervalTimeout=MAXDWORD;
// 把间隔超时设为最大,把总超时设为0将导致ReadFile立即返回并完成操作
TimeOuts.ReadTotalTimeoutMultiplier=0;
//读时间系数
TimeOuts.ReadTotalTimeoutConstant=0;
//读时间常量
TimeOuts.WriteTotalTimeoutMultiplier=50;
//总超时=时间系数*要求读/写的字符数+时间常量
TimeOuts.WriteTotalTimeoutConstant=2000;
//设置写超时以指定WriteComm成员函数中的
二、SetCommTimeouts
要查询当前的超时设置应调用GetCommTimeouts函数,该函数会填充一个COMMTIMEOUTS结构。调用SetCommTimeouts可以用某一个COMMTIMEOUTS结构的内容来设置超时。
有两种超时:间隔超时和总超时。间隔超时是指在接收时两个字符之间的最大时延,总超时是指读写操作总共花费的最大时间。写操作只支持总超时,而读操作两种超时均支持。用COMMTIMEOUTS结构可以规定读/写操作的超时,该结构的定义为:
typedef struct _COMMTIMEOUTS {
DWORD ReadIntervalTimeout; // 读间隔超时
DWORD ReadTotalTimeoutMultiplier; // 读时间系数
DWORD ReadTotalTimeoutConstant; // 读时间常量
DWORD WriteTotalTimeoutMultiplier; // 写时间系数
DWORD WriteTotalTimeoutConstant; // 写时间常量
} COMMTIMEOUTS,*LPCOMMTIMEOUTS;
COMMTIMEOUTS结构的成员都以毫秒为单位。总超时的计算公式是:
总超时=时间系数×要求读/写的字符数 + 时间常量
例如,如果要读入10个字符,那么读操作的总超时的计算公式为:
读总超时=ReadTotalTimeoutMultiplier×10 + ReadTotalTimeoutConstant
可以看出,间隔超时和总超时的设置是不相关的,这可以方便通信程序灵活地设置各种超时。
如果所有写超时参数均为0,那么就不使用写超时。如果ReadIntervalTimeout为0,那么就不使用读间隔超时,如果ReadTotalTimeoutMultiplier和ReadTotalTimeoutConstant都为0,则不使用读总超时。如果读间隔超时被设置成MAXDWORD并且两个读总超时为0,那么在读一次输入缓冲区中的内容后读操作就立即完成,而不管是否读入了要求的字符。
三、SetCommMask
SetCommMask ()函数设置事件掩模来监视指定通信端口上的事件,其原型为:
BOOL SetCommMask( HANDLE hFile, //标识通信端口的句柄 DWORD 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. |