串口小结
一、 概念
串行接口简称串口,也称串行通信接口或串行通讯接口(通常指COM接口),是采用
串行通信方式的扩展接口。
串行接口 (Serial Interface) 是指数据一位一位地顺序传送,其特点是通信线路简单,只要一对传输线就可以实现双向通信(可以直接利用电话线作为传输线),从而大大降低了成本,特别适用于远距离通信,但传送速度较慢。一条信息的各位数据被逐位按顺序传送的通讯方式称为串行通讯。串行通讯的特点是:数据位的传送,按位顺序进行,最少只需一根传输线即可完成;成本低但传送速度慢。串行通讯的距离可以从几米到几千米;根据信息的传送方向,串行通讯可以进一步分为单工、半双工和全双工三种。
二、 使用
在Windows中串口被当做一种文件来看待,因此对它的创建也就和对文件的创建方式
是一致的。
m_hComDev = CreateFile((LPCTSTR)strComName.c_str(),
GENERIC_READ | GENERIC_WRITE, //能对设备进行读写
0, NULL, OPEN_EXISTING, //设备不存在则创建失败
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
NULL);
需要注意其中参数FILE_FLAG_OVERLAPPED通知操作系统对该文件的操作采取异步I/O的方式。
在创建设备句柄时通常需要对其设置许多属性,比如说串口读取超时时间、初始化通信缓冲区、设置串口的波特率、校验、停止位、数据位等等。
(1) 读取超时时间设置
在用ReadFile和WriteFile读写串行口时,需要考虑超时问题。如果在指定的时间
内没有读出或写入指定数量的字符,那么ReadFile或WriteFile的操作就会结束。要查询当前的超时设置应调用GetCommTimeouts函数,该函数会填充一个COMMTIMEOUTS结构。调用SetCommTimeouts可以用某一个COMMTIMEOUTS结构的内容来设置超时。有两种超时:间隔超时和总超时。间隔超时是指在接收时两个字符之间的最大时延,总超时是指读写操作总共花费的最大时间。写操作只支持总超时,而读操作两种超时均支持。
用COMMTIMEOUTS结构可以规定读/写操作的超时,该结构的定义为:
typedef struct _COMMTIMEOUTS {
DWORD ReadIntervalTimeout; //读间隔超时
DWORD ReadTotalTimeoutMultiplier; //读时间系数
DWORD ReadTotalTimeoutConstant; //读时间常量
DWORD WriteTotalTimeoutMultiplier; //写时间系数
DWORD WriteTotalTimeoutConstant; //写时间常量
} COMMTIMEOUTS,*LPCOMMTIMEOUTS;
COMMTIMEOUTS结构的成员都以毫秒为单位。
ReadIntervalTimeout:两字符之间最大的延时,当读取串口数据时,一旦两个字符传输的时间差超过该时间,读取函数将返回现有的数据。设置为0表示该参数不起作用。指定时间最大值(毫秒),允许接收的2个字节间有时间差。也就是说,刚接收了一个字节后,等了ReadIntervalTimeout时间后还没有新的字节到达,就认为本次读串口操作结束(后面的字节等下一次读取操作来处理)。即使你想读8个字节,但读第2个字节后,过了ReadIntervalTimeout时间后,第3个字节还没到。实际上就只读了2个字节。
ReadTotalTimeoutMultiplier:指定比例因子(毫秒),实际上是设置读取一个字节和等待下一个字节所需的时间,这样总的超时时间为读取的字节数乘以该值,同样一次读取操作到达这个时间后,也认为本次读操作己经结束。
ReadTotalTimeoutConstant:一次读取串口数据的固定超时。所以在一次读取串口的操作中,其超时为ReadTotalTimeoutMultiplier乘以读取的字节数再加上 ReadTotalTimeoutConstant。将ReadIntervalTimeout设置为MAXDWORD,并将ReadTotalTimeoutMultiplier和ReadTotalTimeoutConstant设置为0,表示读取操作将立即返回存放在输入缓冲区的字符。可以理解为一个修正时间,实际上就是按ReadTotalTimeoutMultiplier计算出的超时时间再加上该时间才作为整个超时时间。
WriteTotalTimeoutMultiplier:写入每字符间的超时。
WriteTotalTim