在用 ReadFile 和 WriteFile 读写串行口时,需要考虑超时问题.超时的作用是在指
定的时间内没有读入或发送指定数量的字符,ReadFile 或 WriteFile 的操作仍然会
结束.
要查询当前的超时设置应调用 GetCommTimeouts 函数,该函数会填充一个
COMMTIMEOUTS 结构.调用 SetCommTimeouts 可以用某一个 COMMTIMEOUTS 结构的内容
来设置超时.
读写串口的超时有两种:间隔超时和总超时.间隔超时是指在接收时两个字符之间
的最大时延.总超时是指读写操作总共花费的最大时间.写操作只支持总超时,而读
操作两种超时均支持.用 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,那么在读一次输入缓冲区的内容后
读操作就立即返回,而不管是否读入了要求的字符.
在用重叠方式读写串口时,虽然 ReadFile 和 WriteFile 在完成操作以前就可能返
回,但超时仍然是起作用的.在这种情况下,超时规定的是操作的完成时间,而不是
ReadFile 和 WriteFile 的返回时间.
配置串口的示例:
SetupComm(hCom,1024,1024);//输入缓冲区和输出缓冲区的大小都是 1024
COMMTIMEOUTS TimeOuts;
//设定读超时
TimeOuts.ReadIntervalTimeout=1000;
TimeOuts.ReadTotalTimeoutMultiplier=500;
TimeOuts.ReadTotalTimeoutConstant=5000;
//设定写超时
TimeOuts.WriteTotalTimeoutMultiplier=500;
TimeOuts.WriteTotalTimeoutConstant=2000;
SetCommTimeouts(hCom,&TimeOuts);//设置超时
DCB dcb;
GetCommState(hCom,&dcb);
dcb.BaudRate=9600;//波特率为 9600
dcb.ByteSize=8;//每个字节有 8 位
dcb.Parity=NOPARITY;//无奇偶校验位
dcb.StopBits=TWOSTOPBITS;//两个停止位
SetCommState(hCom,&dcb);
PurgeComm(hCom,PURGE_TXCLEAR|PURGE_RXCLEAR);
评论0