0

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 を設定し、クリアしました。以前の状態で読んでいないのは、以前にポートを使用した人のゴミを信頼したくないということです。次に、Baud、Flow Control、および CTS Ignore のみをオプション項目として、すべてのフィールドを設定しました。

だから、私が気づいたことは、デバイスと PC が通信しない状況を作り出すことができるということです。さて、念のために言っておきますが、以前は常にそうであり、常にハイパーターミナル、ProComm、TeraTerm などで動作します。私が見ることができるのは、これらの通信プログラム (および古い VC++ 6 アプリ) が起動すると、デバイスが作成されてセットアップされると、RTS がすぐに高く設定されることです。

さて、私のアプリでは、DCB がセットアップされると、SetCommState が呼び出されます。RTS は常に LOW です。そして、これが起こると、コミュニケーションは乾杯です。

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 (パラメーター エラー) が発生します。そして、私はそれを完全に理解することはできません。SETRTS を高く設定しただけでも、失敗します。

DCB で通信パラメーターを設定した後、Windows で RTS を強制的に高く設定する方法についてのアイデアはありますか?

4

1 に答える 1