前面两篇文章:
串口使用系列学习之什么是串口
串口使用系列学习之什么是流控
介绍了串口及串口流控原理,本篇我们来讨论下,C++如何来进行流控:
一、DCB结构体
typedef struct _DCB { // dcb
DWORD DCBlength; // sizeof(DCB)
DWORD BaudRate; // current baud rate 指定当前的波特率
DWORD fBinary: 1; // binary mode, no EOF check 指定是否允许二进制模式,WINDOWS 95中必须为TRUE
DWORD fParity: 1; // enable parity checking 指定奇偶校验是否允许
DWORD fOutxCtsFlow:1; // CTS output flow control 指定CTS是否用于检测发送控制.当为TRUE是CTS为OFF,发送将被挂起
DWORD fOutxDsrFlow:1; // DSR output flow control 指定DSR是否用于检测发送控制.当为TRUE是DSR为OFF,发送将被挂起
DWORD fDtrControl:2; // DTR flow control type DTR_CONTROL_DISABLE值将DTR置为OFF, DTR_CONTROL_ENABLE值将DTR置为ON, DTR_CONTROL_HANDSHAKE允许DTR"握手",
DWORD fDsrSensitivity:1; // DSR sensitivity 当该值为TRUE时DSR为OFF时接收的字节被忽略
DWORD fTXContinueOnXoff:1; // XOFF continues Tx 指定当接收缓冲区已满,并且驱动程序已经发送出XoffChar字符时发送是否停止.TRUE时,在接收缓冲区接收到缓冲区已满的字节XoffLim且驱动程序已经发送出XoffChar字符中止接收字节之后,发送继续进行。FALSE时,在接收缓冲区接收到代表缓冲区已空的字节XonChar且驱动程序已经发送出恢复发送的XonChar之后,发送继续进行。
DWORD fOutX: 1; // XON/XOFF out flow control TRUE时,接收到XoffChar之后便停止发送.接收到XonChar之后将重新开始
DWORD fInX: 1; // XON/XOFF in flow control TRUE时,接收缓冲区接收到代表缓冲区满的XoffLim之后,XoffChar发送出去.接收缓冲区接收到代表缓冲区空的XonLim之后,XonChar发送出去
DWORD fErrorChar: 1; // enable error replacement 该值为TRUE且fParity为TRUE时,用ErrorChar 成员指定的字符代替奇偶校验错误的接收字符
DWORD fNull: 1; // enable null stripping TRUE时,接收时去掉空(0值)字节
DWORD fRtsControl:2; // RTS flow control RTS_CONTROL_DISABLE时,RTS置为OFF RTS_CONTROL_ENABLE时, RTS置为ON RTS_CONTROL_HANDSHAKE时,当接收缓冲区小于半满时RTS为ON 当接收缓冲区超过四分之三满时RTS为OFF RTS_CONTROL_TOGGLE时,当接收缓冲区仍有剩余字节时RTS为ON ,否则缺省为OFF
DWORD fAbortOnError:1; // abort reads/writes on error TRUE时,有错误发生时中止读和写操作
DWORD fDummy2:17; // reserved 未使用
WORD wReserved; // not currently used 未使用,必须为0
WORD XonLim; // transmit XON threshold 指定在XON字符发送这前接收缓冲区中可允许的最小字节数
WORD XoffLim; // transmit XOFF threshold 指定在XOFF字符发送这前接收缓冲区中可允许的最小字节数
BYTE ByteSize; // number of bits/byte, 4-8 指定端口当前使用的数据位
BYTE Parity; // 0-4=no,odd,even,mark,space 指定端口当前使用的奇偶校验方法,可能为:EVENPARITY,MARKPARITY,NOPARITY,ODDPARITY
BYTE StopBits; // 0,1,2 = 1, 1.5, 2 指定端口当前使用的停止位数,可能为:ONESTOPBIT,ONE5STOPBITS,TWOSTOPBITS
char XonChar; // Tx and Rx XON character 指定用于发送和接收字符XON的值
char XoffChar; // Tx and Rx XOFF character 指定用于发送和接收字符XOFF值
char ErrorChar; // error replacement character 本字符用来代替接收到的奇偶校验发生错误时的值
char EofChar; // end of input character 当没有使用二进制模式时,本字符可用来指示数据的结束
char EvtChar; // received event character 当接收到此字符时,会产生一个事件
WORD wReserved1; // reserved; do not use 未使用
} DCB;
这个结构体主要分为两个部分:
1、常规属性
- BaudRate
指定当前采用的波特率,应与所连接的通讯设备相匹配 - fBinary
二进制模式,无EOF检查,指定是否允许二进制模式。Win32 API不支持非二进制模式传输,应设置为true - fParity
指定奇偶校验是否允许,在为true时具体采用何种校验看Parity 设置 - Parity
值为0-4对应no,odd,even,mark,space 指定端口当前使用的奇偶校验方法,可能为:- EVENPARITY 偶校验
- MARKPARITY 标记校验,所发信息帧第9位恒为1
- NOPARITY 无校验
- ODDPARITY 奇校验
- StopBits
值为0,1,2 对应1, 1.5, 2 指定端口当前使用的停止位数,可能为:- ONESTOPBIT 1停止位
- ONE5STOPBITS 1.5停止位
- TWOSTOPBITS 2停止位
2、流控属性
-
fOutxCtsFlow:
CTS输出流量控制,用来指定是否监控CTS(clear-to-send)信号来做输出流控。当设置为true时:-
若CTS为低电平,则数据发送将被挂起,直至CTS变为高。 CTS的信号一般由DCE(通常是一个Modem)控制,DTE(通常是计算机)发送数据时监测CTS信号。 也就是说DCE通过把CTS置高来表明自己可以接收数据了
-
-
fOutxDsrFlow
DSR输出流量控制,用来指定是否监控DSR (data-set-ready) 信号来做输出流控。当设置为true时: 若DSR为低电平,则数据发送将被挂起,直至DSR变为高。DSR的信号一般由DCE来控制。 -
fDtrControl
DTR流量控制类型,DTR (data-terminal-ready)流控,可取值如下:
取值 | 意义 |
---|---|
DTR_CONTROL_DISABLE | 打开设备时置DTR信号为低电平,应用程序可通过调用EscapeCommFunction 函数来改变DTR线电平状态 |
DTR_CONTROL_ENABLE | 打开设备时置DTR信号为高电平,应用程序可通过调用 EscapeCommFunction函数来改变DTR线电平状态 |
DTR_CONTROL_HANDSHAKE | 允许DTR信号握手,此时应用程序不能调用EscapeCommFunction函数 |
- fDsrSensitivity
通讯设备是否对DSR信号敏感。若设置为TRUE,则当DSR为低时将会忽略所有接收的字节 - fTXContinueOnXoff:
XOFF持续Tx,当输入缓冲区满且驱动程序已发出XoffChar(XOFF)字符时,是否停止发送。- TRUE时,在接收缓冲区接收到超过XoffLim,且驱动程序已经发送出XoffChar(XOFF)字符中止接收,发送仍然会继续。
- FALSE时,则发送会停止, 直至输入缓冲区有XonLim字节的空余空间、驱动程序已发送XonChar(XON)字符之后发送继续。
- fOutX:
XON/XOFF输出流量控制,用于判断发送时是否可用。
如果为TRUE,- 当 XOFF 值被收到的时候,发送停止;
- 当 XON 值被收到的时候,发送继续
- fInX:
XON/XOFF 输入流量控制在接收时是否可用。
如果为TRUE,- 当 输入缓冲区已接收满XoffLim 字节时,发送XOFF字符;
- 当输入缓冲区已经有XonLim 字节的空余容量时,发送XON字符
- fRtsControl:
Rts流量控制,设置RTS (request-to-send)流控,若为0则缺省取 RTS_CONTROL_HANDSHAKE。可取值及其意义:
取值 | 意义 |
---|---|
RTS_CONTROL_DISABLE | 打开设备时置RTS信号为低电平,应用程序可通过调用 EscapeCommFunction函数来改变RTS线电平状态 |
RTS_CONTROL_ENABLE | 打开设备时置RTS信号为高电平,应用程序可通过调用 EscapeCommFunction函数来改变RTS线电平状态 |
RTS_CONTROL_HANDSHAKE | 允许RTS信号握手,此时应用程序不能调用EscapeCommFunction函数。 当输入缓冲区已经有足够空间接收数据时,驱动程序置RTS为高以允许 DCE来发送;反之置RTS为低以阻止DCE发送数据。 |
RTS_CONTROL_TOGGLE | 有字节要发送时RTS变高,当所有缓冲字节已被发送完毕后,RTS变低。 |
- XonLim
传送XON阀值,指定在XON字符发送前,接收缓冲区中可允许的最小字节数
在XON字符发送前接收缓冲区内可允许的最小字节数 - XoffLim
传送XOFF阀值,指定在XOFF字符发送前,接收缓冲区中可允许的最小字节数
在XOFF字符发送前接收缓冲区内可允许的最大字节数 - XonChar
设置Tx和Rx的XON的字符,指定用于发送和接收字符XON的值 - XoffChar
设置Tx和Rx的XON的字符,指定用于发送和接收字符XOFF值
二、流控方法
流控分为硬件流控和软件流控。
硬件流控因为接线方式不同,有几种方式:
- CTS、RTS流控
- CTS、DTR流控
- DSR、RTS流控
- DSR、DTR流控
设置流控代码:
dcb.fDsrSensitivity = FALSE;
dcb.fTXContinueOnXoff = FALSE;
dcb.fRtsControl = RTS_CONTROL_DISABLE;
dcb.fDtrControl = DTR_CONTROL_ENABLE;
switch (g_lpInst->flowControl)
{
//不流控
case NoFlowControl:
{
dcb.fOutxCtsFlow = FALSE;
dcb.fOutxDsrFlow = FALSE;
dcb.fOutX = FALSE;
dcb.fInX = FALSE;
break;
}
//硬件CtsRts流控
case CtsRtsFlowControl:
{
dcb.fOutxCtsFlow = TRUE;
dcb.fOutxDsrFlow = FALSE;
dcb.fRtsControl = RTS_CONTROL_HANDSHAKE;
dcb.fOutX = FALSE;
dcb.fInX = FALSE;
break;
}
//硬件 CtsDtr流控
case CtsDtrFlowControl:
{
dcb.fOutxCtsFlow = TRUE;
dcb.fOutxDsrFlow = FALSE;
dcb.fDtrControl = DTR_CONTROL_HANDSHAKE;
dcb.fOutX = FALSE;
dcb.fInX = FALSE;
break;
}
//硬件DsrRts流控
case DsrRtsFlowControl:
{
dcb.fOutxCtsFlow = FALSE;
dcb.fOutxDsrFlow = TRUE;
dcb.fRtsControl = RTS_CONTROL_HANDSHAKE;
dcb.fOutX = FALSE;
dcb.fInX = FALSE;
break;
}
//硬件DsrDtr流控
case DsrDtrFlowControl:
{
dcb.fOutxCtsFlow = FALSE;
dcb.fOutxDsrFlow = TRUE;
dcb.fDtrControl = DTR_CONTROL_HANDSHAKE;
dcb.fOutX = FALSE;
dcb.fInX = FALSE;
break;
}
//软件流控
case XonXoffFlowControl:
{
dcb.fOutxCtsFlow = FALSE;
dcb.fOutxDsrFlow = FALSE;
dcb.fOutX = TRUE;
dcb.fInX = TRUE;
dcb.XonChar = 0x11;
dcb.XoffChar = 0x13;
dcb.XoffLim = 100;
dcb.XonLim = 100;
break;
}
}