C#自定义串口通信类的实现

转自:https://blog.csdn.net/JustLovePro/article/details/3523348

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. using System.IO.Ports;
  5. using System.Threading;
  6.  
  7. namespace CommPort
  8. {
  9.  
  10.     enum optype
  11.     {
  12.         Continues,
  13.         Orders
  14.     }
  15.  
  16.     /// <summary> 
  17.     /// 串口操作类 
  18.     /// </summary> 
  19.     public class CommOp
  20.     {
  21.         private  SerialPort commport ;
  22.  
  23.         List<byte> list = new List<byte>();
  24.  
  25.         /// <summary> 
  26.         /// 设置标示位,防止close时存在I/O操作 
  27.         /// </summary> 
  28.         bool sign = false;
  29.  
  30.         /// <summary> 
  31.         /// 自定义串口操作类构造函数 
  32.         /// </summary> 
  33.         /// <param name="sp"></param> 
  34.         public CommOp(SerialPort sp)
  35.         {
  36.             this.commport = sp;
  37.         }
  38.  
  39.         public CommOp()
  40.         { 
  41.         }
  42.         /// <summary> 
  43.         /// 连续方式获得磅秤数据,注意磅秤设备应该标定为"连续方式" 
  44.         /// </summary> 
  45.         /// <returns></returns> 
  46.         public string GetContinueData()
  47.         {
  48.             string strReceive = "";
  49.  
  50.             if (sign)
  51.             {
  52.                 byte firstbyte = Convert.ToByte(commport.ReadByte());
  53.  
  54.                 //判断第一个字节是否是起始位:16进制的0x02  
  55.                 if (firstbyte == 0x02)
  56.                 {
  57.                     //定义接收数据长度  
  58.                     int bytesRead = 10;
  59.                     //数据接收字节数组  
  60.                     byte[] bytesData = new byte[bytesRead];
  61.                     //接收字节  
  62.                     byte byteData;
  63.                     for (int i = 0; i <= bytesRead - 1; i++)
  64.                     {
  65.                         try
  66.                         {
  67.                             if (commport.IsOpen)
  68.                             {
  69.                                 byteData = Convert.ToByte(commport.ReadByte());
  70.                                 //判断数据结束字节  
  71.                                 if (byteData == 0x03)
  72.                                 {
  73.                                     break;
  74.                                 }
  75.                                 bytesData[i] = byteData;
  76.                             }
  77.                         }
  78.                         catch (Exception ex)
  79.                         {
  80.                             throw new Exception(ex.Message);
  81.  
  82.                         }
  83.                     }
  84.                     //将字节数组转换成字符串  
  85.                     strReceive = System.Text.Encoding.Default.GetString(bytesData);
  86.                 }
  87.             }
  88.             return GetWeightData(strReceive, optype.Continues);
  89.             
  90.         }
  91.  
  92.         /// <summary> 
  93.         /// 通过上位机指令方式(由通讯协议获得,如:02 41 42 30 33 03)获取磅秤数据,注意磅秤设备应该标定为"指令方式". 
  94.         /// </summary> 
  95.         /// <returns></returns> 
  96.         public string GetDataByOrder(byte[] byts)
  97.         {
  98.             string strReceive = "";
  99.  
  100.             if (sign)
  101.             {   
  102.                 //发送读取指令 
  103.                 commport.Write(byts, 0, byts.Length);
  104.  
  105.                 //等待数据进入缓冲区 
  106.                 Thread.Sleep(500); 
  107.  
  108.                 //接收缓冲区中数据的字节数  
  109.                 int int_Len = commport.BytesToRead;
  110.  
  111.                 //接收数据  
  112.                 byte[] bytes = new byte[int_Len];
  113.                 commport.Read(bytes, 0, int_Len);
  114.  
  115.                 //将数据存入字符串缓冲区中  
  116.                 if (int_Len >= 12)
  117.                 {
  118.                     for (int i = 0; i < bytes.Length; i++)
  119.                     {
  120.                         list.Add(bytes[i]);
  121.                     }
  122.  
  123.                     strReceive = System.Text.Encoding.Default.GetString(list.ToArray());
  124.  
  125.                     list.Clear();
  126.                 }
  127.             }
  128.  
  129.             return GetWeightData(strReceive, optype.Orders);
  130.         }
  131.  
  132.         /// <summary> 
  133.         /// 根据通讯协定分析传输数据(如,有效数据位,小数点位等) 
  134.         /// </summary> 
  135.         /// <param name="data"></param> 
  136.         /// <returns></returns> 
  137.         private string GetWeightData(string data,optype type)
  138.         {
  139.             
  140.             double d = 0;
  141.  
  142.             switch (type)
  143.             {
  144.                 case optype.Orders:
  145.                     d = Convert.ToDouble(data.Substring(4, 6)) / Math.Pow(10, Convert.ToDouble(data.Substring(10, 1)));
  146.                     break;
  147.                 case optype.Continues:
  148.                     d = Convert.ToDouble(data.Substring(1, 6)) / Math.Pow(10, Convert.ToDouble(data.Substring(7, 1)));
  149.                     break;
  150.             }
  151.  
  152.  
  153.           return d.ToString().PadLeft(7,'0');
  154.  
  155.         }
  156.  
  157.         /// <summary> 
  158.         /// 打开串行接口 
  159.         /// </summary> 
  160.         public void Open()
  161.         {
  162.            
  163.             try
  164.             {
  165.                 if (!commport.IsOpen)
  166.                 {
  167.                     commport.Open();//打开串口方法  
  168.                     Thread.Sleep(1500);
  169.                     sign = true;
  170.                 }
  171.  
  172.             }//抛出异常  
  173.             catch (Exception ex)
  174.             {
  175.                 throw new Exception(ex.Message);
  176.             }
  177.         }
  178.  
  179.         /// <summary> 
  180.         /// 关闭串行接口 
  181.         /// </summary> 
  182.         public void Close()
  183.         {
  184.             try
  185.             {
  186.                 if (commport.IsOpen)
  187.                 {
  188.                     sign = false;
  189.                     Thread.Sleep(1500);
  190.                     commport.DiscardInBuffer();
  191.                     commport.Close();
  192.                 }
  193.             }
  194.             catch (Exception ex)
  195.             {
  196.                 throw new Exception(ex.Message);
  197.             }
  198.         }
  199.     }
  200. }
  201.  

这里采用了两种方式进去读取:

1.连续方式:只要磅秤显示有数据,数据就会源源不断的抛入缓冲区,电脑则可以在此时进行读取并分析。通常可以采用serialPort的DataReceived事件处理。

   优点:实时性好。

   缺点:数据过多,分析效果不太好。

2.指令方式:联机电脑发送读取指令给磅秤,磅秤则发送相应的数据信息到缓冲区(没有其他信息),我们可以获取并分析。

    优点:数据单一,分析容易

     缺点:需要手动更新获取数据(可以结合Timer组件实现实时更新数据的效果)。

猜你喜欢

转载自blog.csdn.net/qq_40741855/article/details/81135903