DeviceIoControl && DCB

举报
Amrf 发表于 2018/12/07 09:49:25 2018/12/07
【摘要】 原文:https://blog.csdn.net/songshu5555/article/details/8742652串口流控制DCB结构体解析及设置一、串口通信结构体意义解析:typedef struct _DCB{ DWORD DCBlength;DWORD BaudRate; //波特率DWORD fBinary :1; DWORD fParity :1; //是否奇偶校验DWORD...

win10串口问题

https://answers.microsoft.com/en-us/windows/forum/windows_10-hardware/rs-323-serial-ports-are-not-working-after-updating/df07daf9-0779-4d05-82ec-1f8254882c10

https://blog.csdn.net/ouening/article/details/70947759

https://answers.microsoft.com/en-us/windows/forum/all/serial-comm-port-issues-windows-10-1511/1ced33e6-cc16-4035-b092-4a8535e75162




原文:https://blog.csdn.net/songshu5555/article/details/8742652

串口流控制DCB结构体解析及设置

一、串口通信结构体意义解析:

typedef struct _DCB
{ DWORD DCBlength;
DWORD BaudRate; //波特率
DWORD fBinary :1; 
DWORD fParity :1; //是否奇偶校验
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; //若为TRUE,通讯驱动程序对DSR信号状态敏感。驱动程序将忽略任何接收的字节数,除非DSR调制解调器的输入线为高。
DWORD fTXContinueOnXoff :1; //为TRUE,输入缓冲区内字节已经满XoffLim及驱动程序已经发送XoffChar停止接收字节时,仍然继续发送。为FALSE,输入缓冲区内XonLim是空的,及驱动程序已经发送XonChar字符恢复接收的字节传输后,才会继续接收。
DWORD fOutX :1; //发送方的行为定义,为TRUE时,接收到XoffChar之后便停止发送,接收到XonChar之后将重新开始发送;
DWORD fInX :1;  //接收方的行为定义,为TRUE时,接收缓冲区接收到代表缓冲区满的XoffLim之后,XoffChar发送出去;接收缓冲区空的Buffer达到XonLim之后,XonChar发送出去。
DWORD fErrorChar :1; 
DWORD fNull :1; 
DWORD fRtsControl :2; // RTS Control Flow
//RTS_CONTROL_DISABLE时,RTS置为OFF
//RTS_CONTROL_ENABLE时, RTS置为ON
//RTS_CONTROL_HANDSHAKE时,
//当接收缓冲区小于半满时RTS为ON
//当接收缓冲区超过四分之三满时RTS为OFF
//RTS_CONTROL_TOGGLE时,
//当接收缓冲区仍有剩余字节时RTS为ON ,否则缺省为OFF
DWORD fAbortreplaceString :1; // abort reads/writes on error,为TRUE时,有错误发生时中止读和写操作
DWORD fDummy2 :17; 
WORD wReserved; 
WORD XonLim; //指定在XON字符发送之前接收缓冲区中空缓冲区可允许的最小字节数
WORD XoffLim; //指定在XOFF字符发送这前接收缓冲区中数据缓冲可允许的最小字节数
BYTE ByteSize; 
BYTE Parity; //奇偶校验方式
BYTE StopBits; //停止位
char XonChar;  //请求发送方继续发送时的字符 0x11
char XoffChar; //请求发送方停止发送时的字符 0x13
char ErrorChar; 
char EofChar; 
char EvtChar; 
WORD wReserved1;
} DCB, *LPDCB;

二、设置流控制属性:

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;
}
case CtsRtsFlowControl:
{
    dcb.fOutxCtsFlow = TRUE;
    dcb.fOutxDsrFlow = FALSE;
    dcb.fRtsControl = RTS_CONTROL_HANDSHAKE;
    dcb.fOutX = FALSE;
    dcb.fInX = FALSE;
    break;
}
case CtsDtrFlowControl:
{
    dcb.fOutxCtsFlow = TRUE;
    dcb.fOutxDsrFlow = FALSE;
    dcb.fDtrControl = DTR_CONTROL_HANDSHAKE;
    dcb.fOutX = FALSE;
    dcb.fInX = FALSE;
    break;
}
case DsrRtsFlowControl:
{
    dcb.fOutxCtsFlow = FALSE;
    dcb.fOutxDsrFlow = TRUE;
    dcb.fRtsControl = RTS_CONTROL_HANDSHAKE;
    dcb.fOutX = FALSE;
    dcb.fInX = FALSE;
    break;
}
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;
}

其他:http://com0com.sourceforge.net/examples/LSRMST_INSERT/tstser.cpp

https://social.msdn.microsoft.com/Forums/vstudio/en-US/89b88e89-5814-4819-8b50-7caa3faf5f54/xonxoff-values-in-net20-serialport-class?forum=csharpgeneral

https://blog.csdn.net/SUKHOI27SMK/article/details/8236548

https://www.cnblogs.com/himessage/archive/2012/12/28/2836886.html

https://github.com/enthought/qt-mobility/blob/master/src/systeminfo/qsysteminfo_win.cpp

https://www.cnblogs.com/qq78292959/archive/2012/08/02/2620607.html

https://blog.csdn.net/lujunql/article/details/2532152

https://github.com/enthought/qt-mobility

DCB的使用

连接:

CString strCOM;
strCOM.Format(_T("\\\\.\\"));
strCOM += mComName;
hDevice = INVALID_HANDLE_VALUE;
hDevice = CreateFile(strCOM,GENERIC_READ | GENERIC_WRITE,0,0,OPEN_EXISTING,FILE_FLAG_OVERLAPPED,NULL);
if (hDevice == INVALID_HANDLE_VALUE)
{
return FALSE;
}
DCB dcb;
FillMemory(&dcb, sizeof(dcb), 0);
#if 0
if (!GetCommState(hDevice, &dcb))     // get current DCB
{
// Error in GetCommState
return FALSE;
}
#endif
// Update DCB rate.
dcb.BaudRate = 波特率; //BaudRate[m_BaudRate];
//dcb.ByteSize = 8;
//dcb.Parity = NOPARITY;
//dcb.StopBits = ONESTOPBIT; // (8-N-1)
dcb.ByteSize = 数据位;
dcb.Parity = 校验位;
dcb.StopBits = 停止位;
dcb.fDtrControl=DTR_CONTROL_ENABLE ;//this is common for all handshaking methods
switch(流控制方式)
{
case 1:
dcb.fOutxCtsFlow=TRUE;
dcb.fOutX=FALSE;
dcb.fInX=FALSE;
dcb.fOutxDsrFlow=TRUE;
dcb.fRtsControl=RTS_CONTROL_HANDSHAKE;
break;
case 2:
dcb.fOutX=TRUE;
dcb.fInX=TRUE;
dcb.XonChar = 0x11;
dcb.XoffChar = 0x13;
dcb.fTXContinueOnXoff=TRUE;
dcb.fOutxCtsFlow=FALSE;
dcb.fOutxDsrFlow=FALSE;
dcb.fRtsControl=RTS_CONTROL_ENABLE;
break;
case 0:
default:
dcb.fOutxCtsFlow=FALSE;
dcb.fOutX=FALSE;
dcb.fInX=FALSE;
dcb.fOutxDsrFlow=FALSE;
dcb.fRtsControl=RTS_CONTROL_ENABLE;
break;
}
dcb.fBinary=TRUE;//required for proper operation
// Set new state.
if (!SetCommState(hDevice, &dcb))
{
// Error in SetCommState. Possibly a problem with the communications 
// port handle or a problem with the DCB structure itself.
CloseHandle(hDevice);
hDevice = INVALID_HANDLE_VALUE;
return FALSE;
}
COMMTIMEOUTS timeouts;
// timeouts are not used
timeouts.ReadIntervalTimeout = MAXDWORD; 
timeouts.ReadTotalTimeoutMultiplier = 0;
timeouts.ReadTotalTimeoutConstant = 0;
timeouts.WriteTotalTimeoutMultiplier = 0;
timeouts.WriteTotalTimeoutConstant = 0;
if (!SetCommTimeouts(hDevice, &timeouts))
{
// Error setting time-outs.
CloseHandle(hDevice);
hDevice = INVALID_HANDLE_VALUE;
return FALSE;
}

断开:

SetCommMask(hDevice, 0);
Sleep(100); // sleep for a while for threads to stop
CancelIo(hDevice);
//CancelIoEx(hDevice, NULL);
Sleep(100);
CloseHandle(hDevice);
hDevice = INVALID_HANDLE_VALUE;

使用DeviceIoControl写:

设备自定结构体 Data2Driver;
Data2Driver.bReg = bReg;
Data2Driver.wData = wData;
Data2Driver.bURMReg = bURM;      
if(hDevice != INVALID_HANDLE_VALUE) // hDevice is the port handle obtanined from CreateFile("\\\\.\\COMx"...
{
    BOOL Status;
    DWORD  cbReturned;
    Status =    DeviceIoControl(hDevice, IOCTL_XRUSBPORT_WRITE_UART_REG,&Data2Driver,sizeof(设备自定结构体), NULL, 0,&cbReturned,0);
    if (!Status)
    {           
          // you will get a error message box whenever there is an error
          MessageBox(_T("Error in Writing to USB_UART Reg!"), _T("Error"), MB_OK|MB_ICreplaceString);
          return;
    }
}

使用DeviceIoControl读:

设备自定结构体 Data2Driver;
USHORT Value; 
Data2Driver.bReg = bReg;
Data2Driver.bURMReg = bURM;
if(hDevice != INVALID_HANDLE_VALUE) // hDevice is the port handle obtanined from CreateFile("\\\\.\\COMx"...
{
    BOOL Status;
    DWORD  cbReturned; 
    Status =    DeviceIoControl(hDevice,
                       IOCTL_XRUSBPORT_READ_UART_REG,
                       &Data2Driver,
                       sizeof(设备自定结构体),
                       &Value,
                       sizeof(USHORT),
                       &cbReturned,
                       0);
    if (!Status)
    {          
          // you will get a error message box whenever there is an error
MessageBox(_T("Error in Reading from USB_UART Reg!"), _T("Error"), MB_OK|MB_ICreplaceString);
return 0xFF; // you can also change the return to TRUE and FALSE and use other efficient way for finding the success of the command and thus the data.
}
else
return Value;
}
else
{
  // you will get a error message box whenever there is an error
  MessageBox(_T("The COM Port is not opened for r/w registers!"), _T("Error"), MB_OK|MB_ICreplaceString);
  return 0xFF; // you can also change the return to TRUE and FALSE and use other efficient way for finding the success of the command and thus the data.
}


【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。