DeviceIoControl && DCB
win10串口问题
https://blog.csdn.net/ouening/article/details/70947759
原文: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://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. }
- 点赞
- 收藏
- 关注作者
评论(0)