0

こんにちは、私はシリアル ポート データ受信イベント ハンドラーに取り組んでいます。1 ミリ秒ごとに継続的にデータを受信して​​いる Windows フォームがあり、データ形式は $,0,0,0,0,0,1,0,0,0 です。 ,0,.................0. ここで、$- はフレームの開始を示し、その後に 0 を含む 72 ビットのデータが続き、72 ビットのうちの特定のビットが 1 であり、エラーを示します。メッセージ形式で、1 はエラーを示し、0 は特定のアクションを実行するためのエラーがないことを示します。したがって、シリアルポートからデータを読み取り、配列に保存する必要があります。データが保存されたら、フレームの開始を示すためにドルを探し、それに応じてイベントを追加できる 1 のカウントを探す必要があります。$,0,1,0,0,0....0,0,0,- 72 ビット幅のメッセージ。メッセージ フレームの 1 はデバイスのエラーを示し、それに応じたイベント。

私のコード:

  private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
    {
            List<byte> dataBuffer = new List<byte>();
            var sp = (SerialPort)sender;
             var indata = sp.ReadChar();

             if (indata == 0x24 && dataBuffer.Count == 0)
             {               
                while (serialPort1.BytesToRead > 0)
                     dataBuffer.Add((byte)serialPort1.ReadByte());

                ProcessBuffer(dataBuffer);
                 dataBuffer.Clear();
             }           

        }
         int g=0;
        private void ProcessBuffer(List<byte> comBuffer)
        {
             byte[] dataSend = new byte[serialPort1.BytesToRead];
           for (int c = 0; c <= 72; c++)
             {
                 if (comBuffer[c] == 0x01) 
                {
                     g = c;
                 }
             }


         }                                                                                                                             
4

1 に答える 1

2

DataReceived イベント ハンドラーですべてのバイト (またはビット) を取得すると想定しています。数バイトしか利用できない場合に起動します。少なくとも呼び出しの間にバッファを保持することによって、それに対処する必要があります。このようなもの:

     private List<byte> dataBuffer;

     private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs ek) {
         var sp = (SerialPort)sender;
         if (dataBuffer == null) {
             // Looking for start byte
             if (sp.ReadByte() != 0x24) return;
             dataBuffer = new List<byte>();
         }
         while (sp.BytesToRead > 0) {
             dataBuffer.Add(sp.ReadByte());
             if (dataBuffer.Count == 72 / 8) {
                 // Got all bytes (or bits, it isn't clear), process it
                 var buf = dataBuffer;
                 dataBuffer = null;
                 ProcessBuffer(buf);
                 break;
             }
         }
     }

おそらく「十分なビットが得られた」状態を修正する必要がありますが、質問からは明確ではありませんでした。List はそれほどきれいではありませんが、UI スレッドに BeginInvoke を実行した場合でも、処理中にデータが安定したままであることを確認するための非常に優れた方法です。同時に 1 つのスレッドのみがアクセスすることが確実な場合にのみ、byte[] に置き換えてください。

于 2012-10-26T10:09:07.263 に答える