Windows + SetCommState 如何设置RTS?

Posted

技术标签:

【中文标题】Windows + SetCommState 如何设置RTS?【英文标题】:Windows + SetCommState how to set RTS? 【发布时间】:2013-08-06 21:17:44 【问题描述】:

我有一个从 VC++ 6 移植过来的应用程序,它运行良好。有问题的代码将 WinAPI 用于串行设备驱动程序。移植到 VS2012 时,相同的代码行为会大不相同。

创建一个 DCB,设置 SetCommState 并开始。 CTS 设置为高,RTS 设置为高,您正在路上。

自从移植到 VS2012 Pro MFC 后,我发现不管有没有硬件流控制,它设置的 SetCommState 都是一样的:

memset(&dcb, 0x00, sizeof(dcb));
dcb.DCBlength = sizeof(DCB);

// Must be TRUE, only binary mode in Windows
dcb.fBinary = TRUE;
dcb.fParity = FALSE;

// XOn/XOff disabled
dcb.fTXContinueOnXoff = TRUE;
dcb.fOutX = FALSE;
dcb.fInX = FALSE;
dcb.XonLim = 0;
dcb.XoffLim = 0;
dcb.XonChar = 0;
dcb.XoffChar = 0;

// Misc Stuff
dcb.EofChar = 0;
dcb.EvtChar = 0;
dcb.ErrorChar = 0;
dcb.fErrorChar = FALSE;
dcb.fNull = FALSE;
dcb.fAbortOnError = FALSE;

// 8N1 Setup
dcb.ByteSize = 8;
dcb.Parity = NOPARITY;
dcb.StopBits = ONESTOPBIT;

// Baud Rate
if (dwBaudRate == BAUD_115200)

    dcb.BaudRate = CBR_115200;

else

    dcb.BaudRate = CBR_38400;


// setup hardware flow control
if (bHardware == eYesHardwareFlowControl)

    // ================ FLOW CONTROL ON ================
    switch (bIgnoreCTS)
    
        case eIgnoreCTS:
            dcb.fOutxCtsFlow = FALSE;
            break;

        case eEnableCTS:
            dcb.fOutxCtsFlow = TRUE;
            break;

        default:
        case eCTSDecideLater:
            dcb.fOutxCtsFlow = TRUE;
            break;
    

    // DSR Flow Control
    dcb.fDsrSensitivity = FALSE;
    dcb.fOutxDsrFlow = FALSE;

    // <<Hardware flow control On(TRUE) Off(FALSE)>>
    dcb.fDtrControl = DTR_CONTROL_ENABLE;

    // <<Hardware flow control On(_HANDSHAKE) Off(_ENBLE)>>
    dcb.fRtsControl = RTS_CONTROL_HANDSHAKE;

else

    // ================ FLOW CONTROL OFF ================
    switch (bIgnoreCTS)
    
        case eIgnoreCTS:
            dcb.fOutxCtsFlow = FALSE;
            break;

        case eEnableCTS:
            dcb.fOutxCtsFlow = TRUE;
            break;

        default:
        case eCTSDecideLater:
            dcb.fOutxCtsFlow = FALSE;
            break;
    

    // DSR Flow Control
    dcb.fDsrSensitivity = FALSE;
    dcb.fOutxDsrFlow = FALSE;

    dcb.fDtrControl = DTR_CONTROL_ENABLE;
    dcb.fRtsControl = RTS_CONTROL_ENABLE;


if (SetCommState(m_hIdComDev, &dcb) == WINDOWS_API_ZERO_IS_BAD)

    dwLastError = GetLastError();

此时,我已经设置了 DCB,并清除了它。我没有读到以前的状态是我不想相信以前使用该端口的任何人的任何垃圾。然后我将每个字段设置为波特、流控制和 CTS 忽略作为唯一的可选项目。

所以,我注意到我可以创建设备和 PC 不通信的情况。现在,请注意,他们以前总是这样做,而且他们总是使用 Hyperterminal、ProComm、TeraTerm 等。我可以看到,当这些通讯程序启动(以及旧的 VC++ 6 App)时,当设备被创建和设置时,RTS 立即被设置为高。

现在,我的应用程序,一旦设置了 DCB,就会调用 SetCommState; RTS 始终为低电平。当这种情况发生时,沟通就完蛋了。

我想强制 RTS 变高,并认为我可以这样做:

if (EscapeCommFunction(m_hIdComDev, CLRRTS) == WINDOWS_API_ZERO_IS_BAD)

    dwLastError = GetLastError();


if (EscapeCommFunction(m_hIdComDev, SETRTS) == WINDOWS_API_ZERO_IS_BAD)

    dwLastError = GetLastError();

但这失败了,它给出了一个错误 87(参数错误)。我无法完全弄清楚。即使我只是设置高,它也失败了。

关于在 DCB 中设置通信参数后如何强制 Windows 将 RTS 设置为高的任何想法?

【问题讨论】:

在 DCB 中为 RTS 设置握手或切换时尝试手动设置 RTS 时发生错误 87。我的错误已经够愚蠢了。汉斯的其他物品都得到了照顾。所以剩下的......为什么WinAPI无论如何都会降低RTS? 【参考方案1】:

原来是设备问题,根本不是windows问题。

【讨论】:

以上是关于Windows + SetCommState 如何设置RTS?的主要内容,如果未能解决你的问题,请参考以下文章

如何让Mac,Windows可以互相远程

如何让Mac,Windows可以互相远程

Win7如何加入Windows2003域

如何让Mac,Windows可以互相远程

Windows Server如何创建域并加入域

Windows 11 即将问世 | Windows 10 和 Windows 11 该如何抉择