• Csharp Winfrom 多串口通信


    Csharp 多串口通信

      顾名思义,多串口通信,普通的PC机一般只有一个串口,现在很多家用的PC都没有串口,那么问题来了,如何保证多串口呢?

      有一种神器,MOXA CP-168U Series PCI bus 

      

      需要PCI插槽支持,现在市面上要找大主板才会有PCI。

      OK,硬件准备妥当。当然我这个项目中还需要另外一件神器,红外感应器,暂且不表。

      插入设备,装好驱动,你会在设备管理器中发现 serial board拓展出的8个port。Csharp有针对串口的控件:serialPort,每添加一个物理串口,就需要添加一个控件,操作如下:

      1>.实例化串口并打开

      

       serialPort.PortName = item;  //串口名称
         serialPort.BaudRate = 2400;   //波特率
         serialPort.DataBits = 8;    //数据位
         serialPort.Parity = Parity.Even; //校验位
         serialPort.StopBits = StopBits.One; //停止位
         serialPort.ReadTimeout = 3000;   //读写超时控制在3秒内
         serialPort.WriteTimeout = 3000;

         //设置数据流控制;数据传输的握手协议
         serialPort.Handshake = Handshake.None;
         serialPort.ReceivedBytesThreshold = 1;
         serialPort.RtsEnable = true;

         if (!serialPort.IsOpen)
         {
            serialPort.Open();
         }

      2>.发送数据(byte)

      

    byte[] ReadData = (byte)Function you need did
    serialPort.Write(ReadData, 0, ReadData.Length);
    serialPort.DataReceived += new SerialDataReceivedEventHandler(serialPort1_DataReceived);
    //此处需要特别说明的是,很多人在debug的时候,串口接受回应的事件(serialPort1_DataReceived)没有被触发
    //此时可使用串口调试工具,检查发送的值是否正确,一般情况都是因为命令错误,没有回应,导致DataReceived没有被触发

      3>.接受回应并处理

      

    public void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
            {
                //结束符后,接收返回值           
                int by = serialPort.BytesToRead;
                byte[] rece = new byte[by];
                serialPort.Read(rece, 0, by);
    
                //解析返回值          
               //dosomething
            }        

      如上所述,你只有一个串口需要操作是这样做可以,但是如果你有5个 8头的serial board需要处理时,你就不得不考虑这样做的效率了。那应该怎样呢??

      针对多个串口,可以通过读取注册表获取PC的所有被激活的串口,然后遍历实例化,由于没有使用多线程,不用考虑线程之间的冲突,即使资源被释放,也会在3秒后触发下一个周期

      

         /// <summary>
            /// 打开并设置所有的串口
            /// </summary>
            private void OpenSettingAllSerialPort()
            {
                try
                {
                    Microsoft.Win32.RegistryKey reg = Microsoft.Win32.Registry.LocalMachine;
                    Microsoft.Win32.RegistryKey hardware = reg.OpenSubKey("HARDWARE");
                    Microsoft.Win32.RegistryKey dev = reg.OpenSubKey("DEVICEMAP");
                    Microsoft.Win32.RegistryKey siteKey = reg.OpenSubKey("SERIALCOMM");
    
                    //获取所有串口
                    string[] strPort = System.IO.Ports.SerialPort.GetPortNames();   //siteKey.GetValueNames();
    
                    if (ExcuteNum < 1)
                    {
                        foreach (string item in strPort)
                        {
                            serialPort.PortName = item;  //串口名称
                            serialPort.BaudRate = 2400;   //波特率
                            serialPort.DataBits = 8;    //数据位
                            serialPort.Parity = Parity.Even; //校验位
                            serialPort.StopBits = StopBits.One; //停止位
                            serialPort.ReadTimeout = 3000;   //读写超时控制在3秒内
                            serialPort.WriteTimeout = 3000;
    
                            //设置数据流控制;数据传输的握手协议
                            serialPort.Handshake = Handshake.None;
                            serialPort.ReceivedBytesThreshold = 1;
                            serialPort.RtsEnable = true;
    
                            if (!serialPort.IsOpen)
                            {
                                serialPort.Open();
                            }
    
                            byte[] ReadData = devOpreation.Broadst_Addr();
                            serialPort.Write(ReadData, 0, ReadData.Length);
                            serialPort.DataReceived += new SerialDataReceivedEventHandler(serialPort1_DataReceived);
    
                            ExcuteNum++;
                        }
                    }
                    else
                    {
                        byte[] ReadData = devOpreation.Broadst_Addr();
                        serialPort.Write(ReadData, 0, ReadData.Length);
                        serialPort.DataReceived += new SerialDataReceivedEventHandler(serialPort1_DataReceived);
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show( "串口未找到或被占用. " + ex.Message);                 
                }          
                
            }

      至此,你用很少的代码实现了多串口的实例化并打开,然后发送和接受处理利用同样的场景,问题得到解决。

      到最后这样就是你看到的真实样子。

      

      2015/03/17  TymonYang

  • 相关阅读:
    使用Astah画UML类图经验总结
    Qt的四个常见的图像叠加模式
    获取Linux时间函数
    DBus学习网站
    线程属性pthread_attr_t简介
    Secure CRT 自动记录日志log配置
    MySQL的group_concat()函数合并多行数据
    MySQL的Limit详解
    异步查询json传日期格式到前台,变成了时间戳的格式
    启动studio报错Gradle error
  • 原文地址:https://www.cnblogs.com/tymonyang/p/4344909.html
Copyright © 2020-2023  润新知