zoukankan      html  css  js  c++  java
  • 【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() + "",也许这是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();
    该代码适合主从式通信(一应一答方式)
    绿色通道: 好文要顶 关注我 收藏该文与我联系
    2
    0
    (请您对文章做出评价)
    « 上一篇:.NET牛人应该知道些什么?
    » 下一篇:串口操作

    posted on 2008-07-20 11:53 周伟 阅读(1118) 评论(0) 编辑 收藏

     

  • 相关阅读:
    svn command line tag
    MDbg.exe(.NET Framework 命令行调试程序)
    Microsoft Web Deployment Tool
    sql server CI
    VS 2010 One Click Deployment Issue “Application Validation did not succeed. Unable to continue”
    mshtml
    大厂程序员站错队被架空,只拿着五折工资!苟活和离职,如何选择?
    揭秘!Windows 为什么会蓝屏?微软程序员竟说是这个原因...
    喂!千万别忘了这个C语言知识!(~0 == -1 问题)
    Linux 比 Windows 更好,谁反对?我有13个赞成理由
  • 原文地址:https://www.cnblogs.com/qqhfeng/p/3559658.html
Copyright © 2011-2022 走看看