2

C++のlpBufferReadFileWriteFile、Windows XP ベースの PC とマイクロコントローラー ベースのシステムとの間で通信する関数に使用する変数の型は何ですか? PC には VS2010 C++/CLI の WinForm アプリケーションがあります。マイクロコントローラーのファームウェアは ANSI C です。

私のPCは、コマンド文字(「S」、「C」など)に続いてコマンド終了文字0xd(10進数13の16進数)を送信することになっています。マイクロコントローラベースのシステムは、ASCII 文字と 16 進数の混合である 5 ~ 10 バイトで応答します。たとえば、'V' の後に続く0x41 0x72などです。

PC が送信し、マイクロコントローラーが受信します。

  1. TxMessageとして宣言し、2 のままにしておくPP1と、マイクロコントローラーは 'S' の代わりに'S'を受け取ります。pTxcharnNumberOfBytesToWrite0x530xC30xd

  2. TxMessageとして宣言し、2 のままにしておくPP1と、マイクロコントローラーは「S」のみを受け取ります。pTxwchar_tnNumberOfBytesToWrite0x53

  3. TxMessageとして宣言し、4 のままにしておくPP1と、マイクロコントローラーは「S」に続いて正しく受信します。pTxwchar_tnNumberOfBytesToWrite0x530xd

上記の送信と受信の 3 番目のスキームは、予想されるソリューションの動作を満たしています。しかし、ここで混乱が生じます。PC は 4 バイト (2 つのwcharタイプ) を送信している可能性がありますが、マイクロコントローラーは0x53'S' の 2 バイトを受信し、その後に0xD.

マイクロコントローラーが送信し、PC が受信します。

wchar_tこれが の正しい選択であると仮定すると、マイクロコントローラーから 10 バイトを受信するにはlpBuffer何を選択すればよいでしょうか? nNumberOfBytesToReadReadFile は により 20 バイトを期待しますがwchar_t、マイクロコントローラーは 10 バイトしか送信しません。

驚くべきことに、 ( RxMessagePP2and pRx) をwchar_tcharorとして宣言してもunsigned char、 ReadFile はマイクロコントローラーから 10 バイトを受け取ります (私の予想されるソリューションの動作を満たしています)。しかし、問題は、マイクロコントローラーから「A」を 10 回送信すると、PC 側の ReadFile が「S」のようなジャンクを受信することです0x0, 0xd, 0x54, 0x29.

/// Required designer variable.
HANDLE hCommPort;
BOOL fSuccess;
array<wchar_t> ^ TxMessage;
array<unsigned char> ^ RxMessage;

TxMessage = gcnew array<wchar_t> (12);
RxMessage = gcnew array<unsigned char> (12);


{
TxMessage[0]='S';//target cmd
TxMessage[1]=0xd;//cmd termination character
DWORD dwhandled;
if (hCommPort != INVALID_HANDLE_VALUE)
{
 pin_ptr<wchar_t> pp1 = &TxMessage[0];
 wchar_t *pTx = pp1;
 fSuccess = WriteFile(hCommPort, pTx, 4, &dwhandled, NULL);


 PurgeComm(hCommPort, PURGE_RXABORT|PURGE_TXABORT|PURGE_RXCLEAR|PURGE_TXCLEAR);

 pin_ptr<unsigned char> pp2 = &RxMessage[0];
 unsigned char *pRx = pp2;
 fSuccess = ReadFile(hCommPort, pRx, 10, &dwhandled, NULL);

}//if IsOpen
else{
 this->toolStripStatusLabel4->Text="Port Not Opened";}
}
4

3 に答える 3

1

バイトを使用するのは自然な組み合わせです。シリアル ポートは基本的にバイト指向のデバイスです。送信コードは次のようになります。

bool SendCommand(HANDLE hCommPort) {
    auto TxMessage = gcnew array<Byte> { 'S', '\r' };
    pin_ptr<Byte> pbytes = &TxMessage[0];
    DWORD bytesSent = 0;
    BOOL fSuccess = WriteFile(hCommPort, pbytes, TxMessage->Length, 
                              &bytesSent, NULL);
    return fSuccess && bytesSent == TxMessage->Length);
}

受信コードはさらに作業を行う必要があります。ReadFile() から返されるバイト数は予測できません。読み取りをいつ停止するかを示すプロトコルが必要です。固定長の応答が一般的です。または、特別な最後の文字が非常に一般的です。それは次のようになります。

bool ReceiveResponse(HANDLE hCommPort, array<Byte>^ RxMessage, int% RxCount) {
    for (; RxCount < RxMessage->Length; ) {
        DWORD bytesReceived = 0;
        pin_ptr<Byte> pbytes = &RxMessage[0];
        BOOL fSuccess = ReadFile(hCommPort, pbytes, RxMessage->Length - RxCount, 
                                 &bytesReceived, NULL);
        if (!fSuccess) return false;
        int rxStart = RxCount;
        RxCount += bytesReceived;
        for (int ix = rxStart; ix < RxCount; ++ix) {
            if (RxMessage[ix] == '\r') return true;
        }
    }
    return true;
}

.NET System::IO::Ports::SerialPort クラスを見落とさないでください。文字とバイトの操作を容易にするエンコーディングサポートが組み込まれています。ReceiveResponse() メソッドは、NewLine プロパティが正しく設定された単純な ReadLine() 呼び出しに折りたたまれる可能性があります。

于 2013-08-18T17:05:25.910 に答える
1

ReadFile/WriteFileC++ 型は気にせず、読み取り/書き込みバイト単位で動作します。ReadFileファイル/デバイスから指定されたバイト数 (または、読み取るバイト数が少ない場合はそれ以下) を読み取り、 が指すメモリに配置しますlpBufferWriteFileが指すメモリから、指定されたバイト数をファイル/デバイスに書き込みますlpcBuffer。これらの関数のメモリ バッファは、3 番目のパラメータでこれらの関数に指定したバイト数以上のサイズを持つ、割り当てられたメモリの単なる領域です。

wchat_tマルチバイト型です。サイズは 1 バイトを超える場合があります。したがって、TxMessage[0]='S'; TxMessage[1]=0xd;実際にはメモリ内の 2 バイトではなく、たとえば 4 バイトを埋めることができます。たとえば、表現ではx0053、 などです。その観点からは、そのメモリにどのように、何を入れるかは気にしません。生メモリを読み取り、デバイスに書き込みます。したがって、デバイスが を期待している場合、それを取得していない可能性がありますが、.x000Dwchar_tWriteFilex530Dx0053

全体として、バイトについて考えてください。デバイスに4 バイトを書き込む必要がある場合x0A0B0C0D、この値にバッファをどのように割り当てたかは問題ではありません。カスタムクラスを含む、任意の C++ タイプにすることがunsigned int = x0A0B0C0Dできますchar[ 4 ] = {x0A, x0B, x0C, x0D}int short [ 2 ]= {x0A0B, x0C0D}しかし、渡されたメモリ ポインタが指すメモリの最初の 4 バイトはWriteFilex0A0B0C0D.

同様に、ReadFile指定したバイト数を読み取ります。デバイスが2バイトを送信すると、2バイトReadFileが書き込まれ、渡したポインターが指すメモリに書き込まれます(十分なバイトが割り当てられていることを確認するのはあなたの責任です)。繰り返しますが、2 バイトが割り当てられている限り、どのように割り当てたかは気にしません。その後、再び、必要に応じてこれらの 2 バイトを見ることがchar[ 2 ]できますint short

于 2013-08-18T10:47:15.873 に答える