【C#】串口操作实用类

        做工业通信有很长时间了,特别是串口(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修改了相应的串口驱动。


//注:把代码中的public PortData(string sPortName, int baudrate,Parity parity,SerialInterface.SerialMode mode) 最后一个参数去掉。
PortData comPort = new PortData("COM1:", 115200, Parity.Even);
byte[] bytSendArray = new byte[2]; //发送数据缓冲区
bytSendArray[0]=0xAC;
bytSendArray[2]=0xAA;
byte[] bytReceiveArray = new byte[5];
//该命令潜台词是你发送了两个字节的数据0xAC,0xAA 下位机应该在200毫秒超时内返回5个字节的数据
intReceiveNum = comPort.SendCommand(bytSendData, ref bytReceiveArray, 200);
//intReceiveNum为实际返回的数据个数,返回的数据放在bytReceiveArray中
comPort.Close();
该代码适合主从式通信(一应一答方式)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值