http://topic.csdn.net/u/20071211/10/b8e2d70d-7552-4673-9cc6-17979208294f.html
我用JustinIO类进行串口通讯,可以通过Write和Read函数发送和接收串口数据, 
现在的问题是我不知道何时调用Read函数接收数据,有没有类似6.0那个串口通讯控件的OnComm事件,当有数据时通知我自动接收串口数据如果用线程读取或用Timer时钟读取,间隔时间一般是多少啊? 
还有因为对方发送的数据是不定长的,起始两个字节分别是0x03,0x03,结束有个校验位,每次调用Read函数的时候,读取多长合适呢?

解决方案 »

  1.   

    JustinIO没有怎么用过,不过VS2005中的System.IO.Ports.SerialPort就很好用,你可以建立数据到达事件进行检测是否有数据到达XXXX.DataReceived += new System.IO.Ports.SerialDataReceivedEventHandler(XXXX_DataReceived);另外,据我的经验,串口数据接收的时候是必须有一定的延时,否则缓冲区会有点问题,有可能导致丢数据,据我测试,延时100ms就足够了
      

  2.   

    谢谢楼上解答,不过我用的是VS2003,不是VS2005
      

  3.   

    JustinIO说实话不是很好,对.net支持不是很好。我之前尝试过用JustinIO开发,效果不太理想。劝楼主用SerialPort控件。我用他开发了一款自己感觉功能很强悍的短信软件。SerialPort控件里面有个datareceive的事件,一旦串口有数据就触发这个事件。
    你说的用timer控件定时监控感觉很影响软件性能,起码作为商业软件的话是不能用如此粗糙的方法处理的。至于你说的对数据的读取,我建议你分开处理。因为串口收到数据的类型有别他的结束的“校验位”也有区别,最常见的如ok/r。你可以每次用下readline方法,并把读到的数据加到byte数组里面去。一旦读到的一行以结束的“校验位”结束即结束操作。
      

  4.   

    我用的是VS2003,不是VS2005,用不了SerialPort控件啊
      

  5.   

    那就封装一个事件进去把
    public delegate void ReadEventHandler( object sender, byte [] Buffer );
     class CommPort {//声明事件 
      public event ReadEventHandler ReadEvent;   public bool Done = true;......          //由于JustinIO类网络可以下载,它原有的代码我会省略public void Open()
      {                  .....                  Thread th = new Thread( new ThreadStart( Execut ));
                       th.Start();}private void Execut()
      {
                      while ( Done )
                     {
                            byte [] Buffer = this.Read( 128 );
                            if ( Buffer.Length > 0 )
                             {
                                       OnReadEvent( Buffer );
                             }
                     }
      }private void OnReadEvent( byte [] Buffer )
      {
                     if ( ReadEvent != null )
                    {
                              ReadEvent( this , Buffer );
                     }
      }public void Close() 
      {
                 Done = false;
                 if (hComm!=INVALID_HANDLE_VALUE) 
                  {
                               CloseHandle(hComm);
                   }
      }}就是样已经为JustinIO类添加了一个事件.在调用方只要绑定这人事件就可以了.private CommPort commPort;private void Init()
      {
                commPort = new CommPort();
                commPort.PortNum = "COM1";
                commPort.BaudRate = 9600;
                commPort.ByteSize = 8;
                commPort.Parity = 0;
                commPort.StopBits = 0;//1;
                commPort.ReadTimeout = 2000;
                try
                {
                         if ( commPort.Opened )
                                         commPort.Close();                    commPort.Open();                     if ( commPort.Opened )
                         { 
                                          commPort.ReadEvent += new ReadEventHandler( OnRead );
                          }
                 }
                 catch( Exception ex )
                  {
                                        MessageBox.Show(ex.Message);
                  }
      }
      public void OnRead( object sender , byte [] Buffer )
      {
                    MessageBox.Show( System.Text.Encoding.ASCII.GetString(Buffer ) );
      }
      

  6.   

    我不清楚你用串口具体干嘛,不好说每次读多少字节好,你自己试一下。
    这种读取是阻塞式的,如果没有数据的情况下不会耗cpu资源的。至少在我的程序里面对性能完全没有影响。
      

  7.   

    我的数据最短为13个字节,最长有400~500个字节吧,起始位是0x030x03,接下来是数据长度,后面是数据,最后一位是校验位(即数据字节和)
    我每次间隔3秒读取一次,每次读取500个长度,问题出来了每次读取的数据不是从0x030x03开始的,而是上次遗留下来的数据在前面,然后是0x030x03,后面的数据似乎没读取完,也就是说校验位没有读取到,是不是应该再读取一次,然后把两次的合并到一起呢?如何保证本次数据不遗留到下次?
      

  8.   

    在vs2003时我也用过JustinIO类,确实不怎么好用,而且打开串口时常出问题。后来改用微软的for vs2003,就可以了。你可以试试
    http://msdn.microsoft.com/msdnmag/issues/02/10/NETSerialComm/default.aspx