用vs自带的serialport控件,事件触发,用默认的每收到一个字节就触发 delegate void mydelegate(byte receiveByte);  
byte[] rBuffer = new byte[1024];   //接收缓冲区 
int rIndex = 0;                     //事件处理函数 
private void serialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)    

      byte temp=0; 
        
      mydelegate MyDelegate = new mydelegate(UpdateTextBox); 
      temp = (byte)serialPort.ReadByte();   //读取一个字节 
      this.Invoke(MyDelegate, temp);          
} //数据处理并显示到textbox函数 
public void UpdateTextBox(byte temp) 

      rBuffer[rIndex++] = temp; 
      ... 
} 我现在要收的数据为(02/0184018301810197016100083801530000000000/0083/016/8)这样的格式,我上面这样处理合不合理呢?C#还有没有更好的方法?现在收数据时有这样一个异常,提示索引超出数组界限,搞不明哪里越界了,在this.Invoke(MyDelegate, temp); 出错。用vs自带的serialport控件,事件触发,用默认的每收到一个字节就触发 delegate void mydelegate(byte receiveByte);  
byte[] rBuffer = new byte[1024];   //接收缓冲区 
int rIndex = 0;                     //事件处理函数 
private void serialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)    

      byte temp=0; 
        
      mydelegate MyDelegate = new mydelegate(UpdateTextBox); 
      temp = (byte)serialPort.ReadByte();   //读取一个字节 
      this.Invoke(MyDelegate, temp);          
} //数据处理并显示到textbox函数 
public void UpdateTextBox(byte temp) 

      rBuffer[rIndex++] = temp; 
      ... 
} 我现在要收的数据为(02/0184018301810197016100083801530000000000/0083/016/8)这样的格式,我上面这样处理合不合理呢?C#还有没有更好的方法?现在收数据时有这样一个异常,搞不明哪里越界了,在this.Invoke(MyDelegate, temp); 出错:  
 (原文件名:未命1.jpg) 
引用图片
对串口接收事件还有些疑问,望高手解答一下: 
1、接收事件可以设置接收缓冲区收到多少个字节才触发一次事件,例如我现在设置收到5个字节才触发一次事件,但我现在如果收到的字节数为8个,前5个触发一次事件时取走了,但后面三个还在缓冲区内,是否要等到下一次有数据来凑够5次才触发?那前面8个数据就不完整了,我在程序设了一下,又可以收到8个,不知控件这个是怎样搞的。 
2、我设置每收到一个字节就触发一次事件,是否就像单片机中断一样,收多少个字节就会有多少次事件发生?

解决方案 »

  1.   

    接收事件确实比较恶心。 其实不是1个字节一次,这个是不固定的,有时候1个,有是个n个。
    你要理解串口的本质是对串口缓冲区的操作。 假设激活了事件,这个时候缓冲区里有几个,你就能读出几个
    但是这个时间段中,还有数据陆续再传输,并且陆续添加到缓冲区。
    所以接收事件激活次数。你可以不去管它,就尽量多读取缓冲区的数据即可,可以不用readbyte. 用 read()读一个整个的数据流。private void serialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)

    thread.sleep(500); //稍微延迟一点500-1000ms,使缓冲区数据填充多一些。比如发送过来10个字节,你不加延迟,大概能读到2-3个, 加了延迟,基本可以读出10个完整字节。 
      

  2.   

    com.ReceivedBytesThreshold = 5+2*writeDecimalByteBuff[5];
    可以通过设置com.ReceivedBytesThreshold的值来改变事件触发的频率,即设置收到多少个字节之后触发。
      

  3.   

    不知楼上这个是什么意思com.ReceivedBytesThreshold = 5+2*writeDecimalByteBuff[5];
      

  4.   

    用1楼的方法,在接收事件里sleep个500ms,把全部数据收完后在读,就可以读到一个完整的数据了,按这样看应该只触发了一次事件,而不是收到一个字符触发一次,不知是不是这样?平时写惯单片机程序,换到c#这样真不习惯
      

  5.   


    // 数据接收事件,由SerialPort组件产生
            void _SerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e) 
            {
                
                if (e.EventType != SerialData.Chars)
                {
                    return;
                }            if (_SerialPort.BytesToRead <= 0)
                {
                    return;
                }            byte[] ReadBuf = new byte[_SerialPort.BytesToRead];            _SerialPort.Read(ReadBuf, 0, ReadBuf.Length);            lock (_LockObject)
                {
                    _SharedQueue.Enqueue(ReadBuf);
                }            // 向主线程发送消息.
                PostMessage(_NativeWindow.Handle, MsgId, 0, 0); 
     
            }
      

  6.   

    csdn是怎样看分数的?怎么我积分为0,开贴却有40分可以送的?
      

  7.   

    用1楼的方法,在接收事件里sleep个500ms,把全部数据收完后在读,就可以读到一个完整的数据了,按这样看应该只触发了一次事件,而不是收到一个字符触发一次,不知是不是这样?平时写惯单片机程序,换到c#这样真不习惯