码迷,mamicode.com
首页 > 其他好文 > 详细

串口通讯常用类

时间:2019-05-06 14:17:44      阅读:102      评论:0      收藏:0      [点我收藏+]

标签:else   bool   help   ext   show   port   常用类   csv文件   spl   

1.Mymath

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace BIZHexagonalDevice
{
    class MyMath
    {
        /// <summary>
        /// 字符串转BYTE数组
        /// </summary>
        /// <param name="data"></param>
        /// <returns>高位在前</returns>
        static public byte[] StrToByte(string data)
        {
            byte[] bt = new byte[data.Length / 2];
            for (int i = 0; i < data.Length / 2; i++)
            {
                bt[i] = Convert.ToByte(data.Substring(i * 2, 2), 16);
            }
            return bt;
        }
        /// <summary>
        ///  byte数组转STRING
        /// </summary>
        /// <param name="Bytes"></param>
        /// <returns></returns>
        static public string BytetoStr(byte[] Bytes)
        {
            string str = string.Empty;
            str = BitConverter.ToString(Bytes, 0).Replace("-", string.Empty).ToLower();
            return str;

        }

        /// <summary>
        /// 计算CRC-16
        /// </summary>
        /// <param name="data"></param>
        /// <returns>高位在前</returns>
        static public string CRC_16(string data)
        {
            if ((data.Length % 2) != 0) { throw new Exception("Parameter\"data\"length error"); }
            byte[] tmp = StrToByte(data);

            /*
            1、预置16位寄存器为十六进制FFFF(即全为1)。称此寄存器为CRC寄存器; 
            2、把第一个8位数据与16位CRC寄存器的低位相异或,把结果放于CRC寄存器; 
            3、把寄存器的内容右移一位(朝低位),用0填补最高位,检查最低位; 
            4、如果最低位为0:重复第3步(再次移位); 如果最低位为1:CRC寄存器与多项式A001(1010 0000 0000 0001)进行异或; 
            5、重复步骤3和4,直到右移8次,这样整个8位数据全部进行了处理; 
            6、重复步骤2到步骤5,进行下一个8位数据的处理; 
            7、最后得到的CRC寄存器即为CRC码。
            */
            UInt16 CRCREG = (UInt16)0xffff;
            for (int i = 0; i < tmp.Length; i++)
            {
                CRCREG = (UInt16)(CRCREG ^ (UInt16)tmp[i]);//<< 8;
                for (int j = 0; j < 8; j++)
                {
                    UInt16 CRCtmp = (UInt16)(CRCREG & (UInt16)0x0001);
                    CRCREG = (UInt16)(CRCREG >> (UInt16)1);
                    if (CRCtmp == (UInt16)1)
                    {
                        CRCREG = (UInt16)(CRCREG ^ (UInt16)0xA001);
                    }
                }
            }

            string strtmp = CRCREG.ToString("X4");

            return strtmp.Substring(2, 2) + strtmp.Substring(0, 2);
            //return strtmp;
        }
       
    }
}

2.modbus rtu通讯协议

using System;
using System.Collections.Generic;
using System.Text;
//using WFDLL;

namespace WfpRTU
{
    public class Modbus
    {
        protected string _PortName;

        public string PortName
        {
            get { return _PortName; }
            set
            {
                _PortName = value;
                SP.PortName = _PortName;
            }
        }
        protected int _PortBaud;

        public int PortBaud
        {
            get { return _PortBaud; }
            set
            {
                _PortBaud = value;
                SP.PortBaud = _PortBaud;
            }
        }
        protected int _Timeout;

        public int Timeout
        {
            get { return _Timeout; }
            set
            {
                _Timeout = value;
                SP.Timeout = _Timeout;
            }
        }

        protected System.IO.Ports.Parity _parity;

        public System.IO.Ports.Parity Parity
        {
            get { return _parity; }
            set 
            {
                _parity = value;
                SP.Parity = _parity;
            }
        }

        protected MySerialPort SP = new MySerialPort();

        public Modbus()
        {
        }

        public Modbus(string PName, int PBaud, System.IO.Ports.Parity parity, int timeout)
        {
            _PortName = PName;
            _PortBaud = PBaud;
            _Timeout = timeout;
            _parity = parity;
            SP.PortName = _PortName;
            SP.PortBaud = _PortBaud;
            SP.Timeout = timeout;
            SP.Parity = parity;
        }

        /// <summary>
        /// 读取设备识别码(F0x2B)
        /// </summary>
        /// <param name="CommAddr">通讯地址</param>
        /// <param name="ReadDevId">ReadDevId</param>
        /// <param name="ObjectId">对象ID</param>
        /// <param name="data">数据</param>
        /// <returns></returns>
        public MODBUSRESULT ReadDeviceRegister(string CommAddr, UInt16 ReadDevId, UInt16 ObjectId, out string data)
        {
            if ((CommAddr.Length % 2) != 0) { throw new Exception("CommAddr data length error"); }

            StringBuilder cmd = new StringBuilder();
            cmd.Append(CommAddr);        //通讯地址
            cmd.Append("2B");            //功能码
            cmd.Append("0E");            //MEI类型
            cmd.Append(ReadDevId.ToString("X2"));       //01
            cmd.Append(ObjectId.ToString("X2"));        //00
            cmd.Append(MyMath.CRC_16(cmd.ToString()));
            return SP.SendAndReceive(cmd.ToString(),7, out data);
        }
        /// <summary>
        /// 读取多个线圈
        /// </summary>
        /// <param name="CommAddr">通讯地址</param>
        /// <param name="FunCode">功能码</param>
        /// <param name="StartAddr">起始地址</param>
        /// <param name="RegCount">线圈数</param>
        /// <param name="data">数据</param>
        /// <returns></returns>
        public MODBUSRESULT ReadMultiCoil(string CommAddr, byte FunCode, UInt16 StartAddr, UInt16 RegCount, out string data)
        {
            if ((CommAddr.Length % 2) != 0) { throw new Exception("CommAddr data length error"); }

            StringBuilder cmd = new StringBuilder();
            cmd.Append(CommAddr);        //通讯地址
            cmd.Append(FunCode.ToString("X2"));
            cmd.Append(StartAddr.ToString("X4"));       //起始地址
            cmd.Append(RegCount.ToString("X4"));        //线圈数
            cmd.Append(MyMath.CRC_16(cmd.ToString()));
            double cnt=RegCount / 8;
            return SP.SendAndReceive(cmd.ToString(), Convert.ToUInt16(Math.Ceiling(cnt)) + 4 + CommAddr.Length / 2, out data);
        }

        /// <summary>
        /// 写多个线圈
        /// </summary>
        /// <param name="CommAddr"></param>
        /// <param name="StartAddr"></param>
        /// <param name="RegCount"></param>
        /// <param name="data"></param>
        /// <returns></returns>
        public MODBUSRESULT WriteMultiCoil(string CommAddr, byte FunCode, UInt16 StartAddr, string data)
        {
            if ((data.Length % 2) != 0) { throw new Exception("Data length error"); }

            StringBuilder cmd = new StringBuilder();
            cmd.Append(CommAddr);        //通讯地址
            cmd.Append(FunCode.ToString("X2"));
            cmd.Append(StartAddr.ToString("X4"));       //起始地址
            //int RegCount = data.Length / 4;
            int bytecnt = data.Length / 2;
            int RegCount = bytecnt * 8;//--------------------------------------tgw-------------------
            cmd.Append(RegCount.ToString("X4"));        //寄存器数
            //int bytecnt = RegCount * 2;
            cmd.Append(bytecnt.ToString("X2"));        //字节计数
            cmd.Append(data);
            cmd.Append(MyMath.CRC_16(cmd.ToString()));
            return SP.SendAndReceive(cmd.ToString(), 7 + CommAddr.Length / 2, out data);
        }

        ///// <summary>
        ///// 读取输入寄存器(F0x04)
        ///// </summary>
        ///// <param name="CommAddr">通讯地址</param>
        ///// <param name="StartAddr">起始地址</param>
        ///// <param name="RegNum">寄存器数</param>
        ///// <param name="data">数据</param>
        ///// <returns></returns>
        //public MODBUSRESULT ReadInputRegister(string CommAddr, UInt16 StartAddr, UInt16 RegCount, out string data)
        //{
        //    if ((CommAddr.Length % 2) != 0) { throw new Exception("CommAddr数据长度错误"); }
            
        //    StringBuilder cmd = new StringBuilder();
        //    cmd.Append(CommAddr);        //通讯地址
        //    cmd.Append("04");
        //    cmd.Append(StartAddr.ToString("X4"));       //起始地址
        //    cmd.Append(RegCount.ToString("X4"));        //寄存器数
        //    cmd.Append(MyMath.CRC_16(cmd.ToString()));
        //    return SP.SendAndReceive(cmd.ToString(), RegCount * 2 + 4 + CommAddr.Length / 2, out data);
        //}

        ///// <summary>
        ///// 读取保持寄存器(F0x03)
        ///// </summary>
        ///// <param name="CommAddr">通讯地址</param>
        ///// <param name="StartAddr">起始地址</param>
        ///// <param name="RegNum">寄存器数</param>
        ///// <param name="data">数据</param>
        ///// <returns></returns>
        //public MODBUSRESULT ReadHoldingRegister(string CommAddr, UInt16 StartAddr, UInt16 RegCount, out string data)
        //{
        //    if ((CommAddr.Length % 2) != 0) { throw new Exception("CommAddr数据长度错误"); }
            
        //    StringBuilder cmd = new StringBuilder();
        //    cmd.Append(CommAddr);        //通讯地址
        //    cmd.Append("03");
        //    cmd.Append(StartAddr.ToString("X4"));       //起始地址
        //    cmd.Append(RegCount.ToString("X4"));        //寄存器数
        //    cmd.Append(MyMath.CRC_16(cmd.ToString()));
        //    return SP.SendAndReceive(cmd.ToString(), RegCount * 2 + 4 + CommAddr.Length / 2, out data);
        //}

        /// <summary>
        /// 读取多个寄存器
        /// </summary>
        /// <param name="CommAddr">通讯地址</param>
        /// <param name="FunCode">功能码</param>
        /// <param name="StartAddr">起始地址</param>
        /// <param name="RegCount">寄存器数</param>
        /// <param name="data">数据</param>
        /// <returns></returns>
        public MODBUSRESULT ReadMultiRegister(string CommAddr, byte FunCode,UInt16 StartAddr, UInt16 RegCount, out string data)
        {
            if ((CommAddr.Length % 2) != 0) { throw new Exception("CommAddr data length error"); }
            StringBuilder cmd = new StringBuilder();
            cmd.Append(CommAddr);        //通讯地址
            cmd.Append(FunCode.ToString("X2"));
            cmd.Append(StartAddr.ToString("X4"));       //起始地址
            string str = RegCount.ToString("X4");
            cmd.Append(str);        //寄存器数
            cmd.Append(MyMath.CRC_16(cmd.ToString()));
            return SP.SendAndReceive(cmd.ToString(), RegCount * 2 + 4 + CommAddr.Length / 2, out data);
        }

        /// <summary>
        /// 写多个寄存器
        /// </summary>
        /// <param name="CommAddr"></param>
        /// <param name="StartAddr"></param>
        /// <param name="RegCount"></param>
        /// <param name="data"></param>
        /// <returns></returns>
        public MODBUSRESULT WriteMultiRegister(string CommAddr, byte FunCode, UInt16 StartAddr, string data)
        {
            if ((data.Length % 4) != 0) { throw new Exception("Data length error"); }

            StringBuilder cmd = new StringBuilder();
            cmd.Append(CommAddr);        //通讯地址
            cmd.Append(FunCode.ToString("X2"));
            cmd.Append(StartAddr.ToString("X4"));       //起始地址
            int RegCount = data.Length / 4;
            cmd.Append(RegCount.ToString("X4"));        //寄存器数
            int bytecnt = RegCount * 2;
            cmd.Append(bytecnt.ToString("X2"));        //字节计数
            cmd.Append(data);
            cmd.Append(MyMath.CRC_16(cmd.ToString()));
            return SP.SendAndReceive(cmd.ToString(), 7 + CommAddr.Length / 2, out data);
        }


        public static string GetResultMsg(MODBUSRESULT ret)
        {
            string msg = "";
            switch (ret)
            {
                case MODBUSRESULT.DataAddrInvalid:
                    msg = "Data address invalid";
                    break;
                case MODBUSRESULT.DataCheckFall:
                    msg = "Data validation failure";
                    break;
                case MODBUSRESULT.DataFormatError:
                    msg = "Data format error";
                    break;
                case MODBUSRESULT.DataValueInvalid:
                    msg = "Data value invalid";
                    break;
                case MODBUSRESULT.OK:
                    msg = "Correct";
                    break;
                case MODBUSRESULT.PortOpenFall:
                    msg = "Open port failure";
                    break;
                case MODBUSRESULT.Timeout:
                    msg = "Communication timeout";
                    break;
                case MODBUSRESULT.UnknownError:
                    msg = "Unknown error";
                    break;
                case MODBUSRESULT.UnknownFunCode:
                    msg = "Unsupported function code";
                    break;
                default:
                    msg = "Unknown error";
                    break;
            }
            return msg;
        }

        public static string GetRegValue(string data,int StartReg,int RegNum)//按字符
        {
            int offset = 6;
            int startpoint = offset + StartReg * 4;
            int len = RegNum * 4;
            return data.Substring(startpoint, len).ToUpper();
        }

        public static string GetByteValue(string data, int StartReg, int RegNum)//按字符
        {
            int offset = 6;
            int startpoint = offset + StartReg * 2;
            int len = RegNum * 2;
            return data.Substring(startpoint, len).ToUpper();
        }
    }
}

3.csv文件读写

/*
 * Created by SharpDevelop.
 * User: sz
 * Date: 2007/12/10
 * Time: 18:09
 * 
 * To change this template use Tools | Options | Coding | Edit Standard Headers.
 */

using System;
using System.Collections.Generic;
using System.IO;
using System.Text;

namespace WfpRTU
{
	/// <summary>
	/// CSVUtil is a helper class handling csv files.
	/// </summary>
	public class CSVUtil
	{
		private CSVUtil()
		{
		}
		//write a new file, existed file will be overwritten
		public static void WriteCSV(string filePathName,List<String[]>ls)
		{
			WriteCSV(filePathName,false,ls);
		}
		//write a file, existed file will be overwritten if append = false
		public static void WriteCSV(string filePathName,bool append, List<String[]> ls)
		{
			StreamWriter fileWriter=new StreamWriter(filePathName,append,Encoding.Default);
			foreach(String[] strArr in ls)
			{
				fileWriter.WriteLine(String.Join(",",strArr));
			}
			fileWriter.Flush();
			fileWriter.Close();
			
		}
		public static List<String[]> ReadCSV(string filePathName)
		{
			List<String[]> ls = new List<String[]>();
			StreamReader fileReader=new   StreamReader(filePathName);  
			string strLine="";
			while (strLine != null)
			{
				strLine = fileReader.ReadLine();
				if (strLine != null && strLine.Length>0)
				{
					ls.Add(strLine.Split(‘,‘));
					//Debug.WriteLine(strLine);
				}
			} 
			fileReader.Close();
			return ls;
		}
		
	}
}

  4.串口接收触发事件

 private void Com_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            Thread.Sleep(1000);
            if (Com.IsOpen)
            {
                try
                {
                    byte[] ReDatas = new byte[Com.BytesToRead];
                    if (Com.BytesToRead <= 0)
                    {
                        txtData.Text = "没查询到数据,请检查设置";

                    }

                    else
                    {
                        Com.Read(ReDatas, 0, ReDatas.Length);
                        string temHex = BytesToHex(ReDatas);
                    
                    }
                catch (Exception ex)
                {

                    MessageBox.Show(ex.Message, "出错提示!!!!!");
                    txtData.Text = "";
                }

            }
            else
            {
                txtData.Clear();
                txtData.Text = "请检查串口是否打开";
            }
        }

  

 

串口通讯常用类

标签:else   bool   help   ext   show   port   常用类   csv文件   spl   

原文地址:https://www.cnblogs.com/-CarryRao/p/10819304.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!