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 を強制的に高く設定する方法についてのアイデアはありますか?