网站建议:179001057@qq.com

【C#】串口操作实用类

技术2022-05-11  1

做工业通信有很长时间了,特别是串口(232/485),有VB/VC/C各种版本的串口操作代码,这些代码也经过了多年的现场考验,应该说是比较健壮的代码,但是目前却没有C#相对成熟的串口操作代码,最近用Moxa的设备开发基于WinCE5.0的串口操作代码,所以就扩充完善了一下串口操作,特别是SendCommand函数,这是我比较常用的主从通信代码,不喜欢用事件或线程接数据,在规定的超时时间内直接循环判断要接收的数据。

     下面是具体的代码:   

   public   class  PortData    {         public   event  PortDataReceivedEventHandle Received;         public   event  SerialErrorReceivedEventHandler Error;          public  SerialPort port;         public   bool  ReceiveEventFlag  =   false ;   // 接收事件是否有效 false表示有效          public  PortData( string  sPortName,  int  baudrate,Parity parity,SerialInterface.SerialMode mode)        {            port  =   new  SerialPort(sPortName, baudrate, parity,  8 , StopBits.One);            port.RtsEnable  =   true ;            port.ReadTimeout  =   3000 ;            port.DataReceived  +=   new  SerialDataReceivedEventHandler(DataReceived);            port.ErrorReceived  +=   new  SerialErrorReceivedEventHandler(ErrorEvent);        }         ~ PortData()        {            Close();        }         public   void  Open()        {             if  ( ! port.IsOpen)            {                           port.Open();            }        }         public   void  Close()        {             if  (port.IsOpen)            {                port.Close();            }        }         // 数据发送          public   void  SendData( byte [] data)        {             if  (port.IsOpen)            {                port.Write(data,  0 , data.Length);            }        }         public   void  SendData( byte [] data, int  offset, int  count)        {             if  (port.IsOpen)            {                port.Write(data, offset, count);            }        }         // 发送命令          public   int  SendCommand( byte [] SendData,  ref    byte [] ReceiveData, int  Overtime)        {             if (port.IsOpen)            {                ReceiveEventFlag  =   true ;         // 关闭接收事件                 port.DiscardInBuffer();          // 清空接收缓冲区                                  port.Write(SendData,  0 , SendData.Length);                 int  num = 0 ,ret = 0 ;                 while  (num ++   <  Overtime)                {                     if  (port.BytesToRead  >=  ReceiveData.Length)  break ;                    System.Threading.Thread.Sleep( 1 );                 }                 if  (port.BytesToRead  >=  ReceiveData.Length)                     ret  =  port.Read(ReceiveData,  0 , ReceiveData.Length);                ReceiveEventFlag  =   false ;        // 打开事件                  return  ret;            }             return   - 1 ;        }         public   void  ErrorEvent( object  sender, SerialErrorReceivedEventArgs e)        {             if  (Error  !=   null ) Error(sender, e);        }         // 数据接收          public   void  DataReceived( object  sender, SerialDataReceivedEventArgs e)        {             // 禁止接收事件时直接退出              if  (ReceiveEventFlag)  return ;             byte [] data  =   new   byte [port.BytesToRead];            port.Read(data,  0 , data.Length);             if  (Received  !=   null ) Received(sender,  new  PortDataReciveEventArgs(data));        }         public   bool  IsOpen()        {             return  port.IsOpen;        }    }     public   delegate   void  PortDataReceivedEventHandle( object  sender, PortDataReciveEventArgs e);     public   class  PortDataReciveEventArgs : EventArgs    {         public  PortDataReciveEventArgs()        {             this .data  =   null ;        }         public  PortDataReciveEventArgs( byte [] data)        {             this .data  =  data;        }         private   byte [] data;         public   byte [] Data        {             get  {  return  data; }             set  { data  =  value; }        }    }

【附注】1~9 串口的名称是 "COMx:",>9的以前用.//COMx:比较好使,但是在moxa 661设备上却不行,要用如下格式"$device//COM" + PortNo.ToString() + "/0",也许这是moxa修改了相应的串口驱动。

叶帆工作室(csdn)相关连接:http://blog.csdn.net/yefanqiu/archive/2007/03/27/1543187.aspx


最新回复(0)