电脑与MCGS通过ModbusRTU协议通讯示例

最近学习了ModbusRTU协议,自己就用C#编写了一个ModbusRTU类库,用来和MCGS触摸屏做通讯,因本人新手一个,编出来的类库可能还有漏洞,修望大家多包涵。
这是我编写的类库下载地址MCGSModbusRTU类库
也可以看我下面的代码自己编写。

一、基础设置

1、MCGS设置

因为是与MCGS通讯,首先要设置MCGS的参数。我用的屏型号TPC7032Kt ,屏的编程软件是McgsPro组态软件。这款屏的通讯端口为3个,一个232,两个485.这是三个通讯端口的针脚定义
要添加一个父类设备和和一个数据转发设备

设置父设备的参数,我用的端口号为COM2,波特率9600,数据位8,停止位1,数据校验为 无校验。
在这里插入图片描述
数据转发设置,设备地址为1,数据组码顺序数据按默认,字符串选择Unicode,支持中文编码,这个影响你后面对数据进行解析,我的类库也是按照这个顺序进行解析的,感兴趣的可以自己改变,然后自己进行解析。
在这里插入图片描述
触摸屏的参数就设置好了,剩下的就是关联变量。需要说明MCGS的地址是从1开始的,而我们用电脑读写是从0开始的。

2、创建引用类库

现在可以开始编类库了,因为我们这个类库是要在Windows窗体中来使用,所以我创建的这个类库为 .NET Framework 类库。
在这里插入图片描述
为了调试需要,还要创建Windows窗体,然后在窗体中添加引用,因为我是在同一个解决方案下,可以直接添加引用。类库生成的是.dll文件。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
直接添加.dll文件
在这里插入图片描述
在这里插入图片描述

二、编写类库

1、编写类库接口

以后有可能对这个类库进行扩展,能够走TCP协议,就声明了一个接口,这个不是必须的,

namespace MCGSModbus
{
    /// <summary>
    /// MCGS通讯接口类
    /// </summary>
    interface IMCGSData
    {

        #region 读取数据

        /// <summary>
        /// 读取bool数据结果
        /// </summary>
        /// <param name="slaveld">读取从站的地址</param>
        /// <param name="functionCode">读取的功能码 值为 01 02 03 04  </param>
        /// <param name="startAddress">读取的起始地址 偏移地址  读取的地址从0开始</param>
        /// <param name="count">读取的数据长度</param>
        /// <returns>读取到的值  返回null则读取失败</returns>
        bool[] ReadBool(byte slaveld, byte functionCode, ushort startAddress, ushort count);
        
        /// <summary>
        /// 读取浮点数
        /// </summary>
        /// <param name="slaveld">从站地址</param>
        /// <param name="functionCode">功能码 03 04 </param>
        /// <param name="startAddress">读取的起始地址 偏移地址</param>
        /// <param name="count">读取数据的个数</param>
        /// <returns>读取到的值  返回null则读取失败</returns>
         float[] ReadFloat(byte slaveld, byte functionCode, ushort startAddress, ushort count);
       
        /// <summary>
        /// 读取32位整数
        /// </summary>
        /// <param name="slaveld">从站地址</param>
        /// <param name="functionCode">功能码 03 04 </param>
        /// <param name="startAddress">读取的起始地址 偏移地址</param>
        /// <param name="count">读取数据的个数</param>
        /// <returns>读取到的值  返回null则读取失败</returns>
         int[] ReadInt(byte slaveld, byte functionCode, ushort startAddress, ushort count);
       
        /// <summary>
        /// 读取32位无符号整数
        /// </summary>
        /// <param name="slaveld">从站地址</param>
        /// <param name="functionCode">功能码 03 04 </param>
        /// <param name="startAddress">读取的起始地址 偏移地址</param>
        /// <param name="count">读取数据的个数</param>
        /// <returns>读取到的值  返回null则读取失败</returns>
         uint[] ReadUint(byte slaveld, byte functionCode, ushort startAddress, ushort count);
       
        /// <summary>
        /// 读取16位整数
        /// </summary>
        /// <param name="slaveld">从站地址</param>
        /// <param name="functionCode">功能码 03 04 </param>
        /// <param name="startAddress">读取的起始地址 偏移地址</param>
        /// <param name="count">读取数据的个数</param>
        /// <returns>读取到的值  返回null则读取失败</returns>
         short[] ReadShore(byte slaveld, byte functionCode, ushort startAddress, ushort count);
       
        /// <summary>
        /// 读取16位无符号整数
        /// </summary>
        /// <param name="slaveld">从站地址</param>
        /// <param name="functionCode">功能码 03 04 </param>
        /// <param name="startAddress">读取的起始地址 偏移地址</param>
        /// <param name="count">读取数据的个数</param>
        /// <returns>读取到的值  返回null则读取失败</returns>
         ushort[] ReadUshore(byte slaveld, byte functionCode, ushort startAddress, ushort count);
        
        /// <summary>
        /// 读取字符串 格式是ASCII 不能表示中文
        /// </summary>
        /// <param name="slaveld">从站地址</param>
        /// <param name="functionCode">功能码 03 04 </param>
        /// <param name="startAddress">读取的起始地址 偏移地址</param>
        /// <param name="count">读取字符的个数 </param>
        /// <returns>读取到的值  返回null则读取失败</returns>
         string ReadStringASCII(byte slaveld, byte functionCode, ushort startAddress, ushort count);
        
       
        /// <summary>
        /// 读取字符串 格式是Unicode 可以表示中文
        /// </summary>
        /// <param name="slaveld">从站地址</param>
        /// <param name="functionCode">功能码 03 04 </param>
        /// <param name="startAddress">读取的起始地址 偏移地址</param>
        /// <param name="count">读取字符的个数 </param>
        /// <returns>读取到的值  返回null则读取失败</returns>
         string ReadStringUnicode(byte slaveld, byte functionCode, ushort startAddress, ushort count);
       

        #endregion

        #region 写入数据
        /// <summary>
        /// 写入16位无符号整数
        /// </summary>
        /// <param name="slaveld">从站地址</param>
        /// <param name="startAddress">写入的起始地址 偏移地址</param>
        /// <param name="value">写入的数据</param>
        /// <returns>写入的结果 成功返回true</returns>
         bool Write16(byte slaveld, ushort startAddress, ushort value);
       
      
        /// <summary>
        /// 写入16位整数
        /// </summary>
        /// <param name="slaveld">从站地址</param>
        /// <param name="startAddress">写入的起始地址 偏移地址</param>
        /// <param name="value">写入的数据</param>
        /// <returns>写入的结果 成功返回true</returns>
         bool Write16(byte slaveld, ushort startAddress, short value);
        

        /// <summary>
        /// 写入多个16位整数
        /// </summary>
        /// <param name="slaveld">从站地址</param>
        /// <param name="startAddress">写入的起始地址 偏移地址</param>
        /// <param name="count">写入的个数</param>
        /// <param name="value">写入的数据</param>
        /// <returns>写入的结果 成功返回true</returns>
        bool Write16(byte slaveld, ushort startAddress, ushort count, short[] value);
        
        /// <summary>
        /// 写入多个16位无符号整数
        /// </summary>
        /// <param name="slaveld">从站地址</param>
        /// <param name="startAddress">写入的起始地址 偏移地址</param>
        /// <param name="count">写入的个数</param>
        /// <param name="value">写入的数据</param>
        /// <returns>写入的结果 成功返回true</returns>
        bool Write16(byte slaveld, ushort startAddress, ushort count, ushort[] value);
       
        /// <summary>
        /// 写入32位整数
        /// </summary>
        /// <param name="slaveld">从站地址</param>
        /// <param name="startAddress">写入的起始地址 偏移地址</param>
        /// <param name="value">写入的数据</param>
        /// <returns>写入的结果 成功返回true</returns>
         bool Write32(byte slaveld, ushort startAddress, int value);
      
        /// <summary>
        /// 写入32位无符号整数
        /// </summary>
        /// <param name="slaveld">从站地址</param>
        /// <param name="startAddress">写入的起始地址 偏移地址</param>
        /// <param name="value">写入的数据</param>
        /// <returns>写入的结果 成功返回true</returns>
         bool Write32(byte slaveld, ushort startAddress, uint value);
       
        /// <summary>
        /// 写入多个32位无符号整数
        /// </summary>
        /// <param name="slaveld">从站地址</param>
        /// <param name="startAddress">写入的起始地址 偏移地址</param>
        /// <param name="count">写入的个数</param>
        /// <param name="value">写入的数据</param>
        /// <returns>写入的结果 成功返回true</returns>
         bool Write32(byte slaveld, ushort startAddress, ushort count, uint[] value);
       

        /// <summary>
        /// 写入多个32位整数
        /// </summary>
        /// <param name="slaveld">从站地址</param>
        /// <param name="startAddress">写入的起始地址 偏移地址</param>
        /// <param name="count">写入的个数</param>
        /// <param name="value">写入的数据</param>
        /// <returns>写入的结果 成功返回true</returns>
         bool Write32(byte slaveld, ushort startAddress, ushort count, int[] value);
       

        /// <summary>
        /// 写入32位浮点数
        /// </summary>
        /// <param name="slaveld">从站地址</param>
        /// <param name="startAddress">写入的起始地址 偏移地址</param>
        /// <param name="value">写入的数据  </param>
        /// <returns>写入的结果 成功返回true</returns>
         bool Write32(byte slaveld, ushort startAddress, float value);
       
        /// <summary>
        /// 写入多个32位浮点数
        /// </summary>
        /// <param name="slaveld">从站地址</param>
        /// <param name="startAddress">写入的起始地址 偏移地址</param>
        /// <param name="count">写入的个数</param>
        /// <param name="value">写入的数据</param>
        /// <returns>写入的结果 成功返回true</returns>
         bool Write32(byte slaveld, ushort startAddress, ushort count, float[] value);
      

        /// <summary>
        /// 写入字符串
        /// </summary>
        /// <param name="slaveld">从站地址</param>
        /// <param name="startAddress">写入的起始地址 偏移地址</param>
        /// <param name="value">写入的数据  </param>
        /// <returns>写入的结果 成功返回true</returns>
         bool WriteString(byte slaveld, ushort startAddress, string value);
        

        /// <summary>
        /// 写入单个布尔值
        /// </summary>
        /// <param name="slaveld">从站地址</param>
        /// <param name="functionCode">功能码 功能码为05 06 </param>
        /// <param name="startAddress">写入偏移地址</param>
        /// <param name="value">写入数据</param>
        /// <returns>写入是否成功 成功返回true</returns>
         bool WriteBool(byte slaveld, byte functionCode, ushort startAddress, ushort value);
       


        #endregion



    }
}

接下来写ModbusRTU类库。
首先让这个类库继承接口,在类中实现接口。
在这里插入图片描述

2、编写链接、断开方法

建立串口实例,建立链接

         /// <summary>
        /// 打开串口
        /// </summary>
        /// <param name="portName">端口号</param>
        /// <param name="baudRate">波特率</param>
        /// <param name="paritys">校验位 值为 无 奇 偶 </param>
        /// <param name="dataBist">数据位 值为 8或7 </param>
        /// <param name="stopBits">停止位  值为 0 1 2</param>
        public void OpenCOM(string portName, int baudRate, string  paritys, int dataBist,int stopBits)
        {
           //声明校验类型并赋值默认值
            Parity parity = Parity.None;
            //根基传入的参数来赋值
            switch (paritys)
            {
                case "无":
                     parity = Parity.None;
                    break;

                case "偶":
                    parity = Parity.Even;
                    break;
                case "奇":
                    parity = Parity.Odd;
                    break;
                default:
                  
                    break;
            }
            //创建串口实例
            CurrentCOM = new SerialPort();
            //设置端口号
            CurrentCOM.PortName = portName;
            //设置波特率
            CurrentCOM.BaudRate = baudRate;
            //设置奇偶校验
            CurrentCOM.Parity = parity;
            //设置数据位
            CurrentCOM.DataBits = dataBist;
            //设置停止位
            CurrentCOM.StopBits = (StopBits)stopBits;
            
            //判断端口是否打开,打开就关掉
            if (CurrentCOM.IsOpen)
            {
                CurrentCOM.Close();
            }
            //打开串口
            CurrentCOM.Open();
        }

关闭串口

 /// <summary>
        /// 关闭串口
        /// </summary>
        public void CloseCOM()
        {
            //关闭串口
            if (CurrentCOM.IsOpen)
            {
                CurrentCOM.Close();
            }
        }

3、编写数据处理方法

把二进制字符数组转换成布尔值

 /// <summary>
        /// 把二进制字符串数组转成布尔数组
        /// </summary>
        /// <param name="str">要转换的字符数组</param>
        /// <returns>转换后的布尔数组,失败返回  null</returns>
        private bool[] CharacterToBoolean(char[] str)
        {
            bool[] b = new bool[str.Length];
            for (int i = 0; i < str.Length; i++)
           {
                if (str[i] == '1' || str[i] == '0')
                {
                    //判断字符是否等1
                    b[i] = (str[i] == '1' ? true : false);
                }
                else return null;
            }
            return b;
        }

16位数据高低位交换

        /// <summary>
        /// 16位数据高低位置转换
        /// </summary>
        /// <param name="by">要转换的数据</param>
        private void ReverseBytes16(byte[] by)
        {
            List<byte> SendCommand = new List<byte>();

            byte[] byt = new byte[2];
            for (int i = 0; i < by.Length; i += 2)
            {
                byt[0] = by[i];
                byt[1] = by[i + 1];
                Array.Reverse(byt);
                SendCommand.AddRange(byt);

            }
            Array.Copy(SendCommand.ToArray(), by, SendCommand.Count);
        }

32位数据进行高低位交换


        /// <summary>
        /// 32位数据高低位置转换
        /// </summary>
        /// <param name="by">要转换的数据</param>
        private void ReverseBytes32(byte[] by)
        {
            List<byte> SendCommand = new List<byte>();

            byte[] byt = new byte[4];
            for (int i = 0; i < by.Length; i +=4)
            {
                byt[0] = by[i];
                byt[1] = by[i + 1];
                byt[2] = by[i+2];
                byt[3] = by[i + 3];
                Array.Reverse(byt);
                SendCommand.AddRange(byt);

            }
            Array.Copy(SendCommand.ToArray(), by, SendCommand.Count);
        }

字节数组转换成数据,使用C#内部方法

     //数据转换成二进制字符串  result数据
    char[] intermediate = Convert.ToString(result, 2).ToArray();
   //转换成32位浮点数   result字节数组  
    float  intermediate = BitConverter.ToSingle(result, 4);
    //转换成32位整数    result字节数组 
   int intermediate = BitConverter.ToInt32(result,  4);
     //转换成32位无符号整数  result字节数组
   uint intermediate = BitConverter.ToUInt32(result,  4);
    //转换成16位整数    result字节数组
    short intermediate = BitConverter.ToInt16(result,  2);
    //转换成16位无符号整数    result字节数组
  ushort  intermediate = BitConverter.ToUInt16(result,  2);
   //字节数组转换成字符串  result字节数组   
   string intermediate = Encoding.ASCII.GetString(result, 0, result.Length);
    //字节数组转换成字符串  result字节数组 
   string  intermediate = Encoding.Unicode.GetString(result, 0, result.Length);
   
      

4、CRC16校验

这是从网上找的校验方法

 #region CRC16校验
        private static readonly byte[] aucCRCHi = {
            0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
            0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
            0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
            0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
            0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
            0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
            0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
            0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
            0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
            0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
            0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
            0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
            0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
            0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
            0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
            0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
            0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
            0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
            0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
            0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
            0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
            0x00, 0xC1, 0x81, 0x40



       };

        private static readonly byte[] aucCRCLo = {
            0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06, 0x07, 0xC7,
            0x05, 0xC5, 0xC4, 0x04, 0xCC, 0x0C, 0x0D, 0xCD, 0x0F, 0xCF, 0xCE, 0x0E,
            0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09, 0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9,
            0x1B, 0xDB, 0xDA, 0x1A, 0x1E, 0xDE, 0xDF, 0x1F, 0xDD, 0x1D, 0x1C, 0xDC,
            0x14, 0xD4, 0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3,
            0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3, 0xF2, 0x32,
            0x36, 0xF6, 0xF7, 0x37, 0xF5, 0x35, 0x34, 0xF4, 0x3C, 0xFC, 0xFD, 0x3D,
            0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A, 0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38,
            0x28, 0xE8, 0xE9, 0x29, 0xEB, 0x2B, 0x2A, 0xEA, 0xEE, 0x2E, 0x2F, 0xEF,
            0x2D, 0xED, 0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26,
            0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60, 0x61, 0xA1,
            0x63, 0xA3, 0xA2, 0x62, 0x66, 0xA6, 0xA7, 0x67, 0xA5, 0x65, 0x64, 0xA4,
            0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F, 0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB,
            0x69, 0xA9, 0xA8, 0x68, 0x78, 0xB8, 0xB9, 0x79, 0xBB, 0x7B, 0x7A, 0xBA,
            0xBE, 0x7E, 0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5,
            0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71, 0x70, 0xB0,
            0x50, 0x90, 0x91, 0x51, 0x93, 0x53, 0x52, 0x92, 0x96, 0x56, 0x57, 0x97,
            0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C, 0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E,
            0x5A, 0x9A, 0x9B, 0x5B, 0x99, 0x59, 0x58, 0x98, 0x88, 0x48, 0x49, 0x89,
            0x4B, 0x8B, 0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C,
            0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42, 0x43, 0x83,
            0x41, 0x81, 0x80, 0x40


        };
        /// <summary>
        /// CRC校验
        /// </summary>
        /// <param name="pucFrame">要校验的字节数组</param>
        /// <param name="uslen">要校验的字节个数</param>
        /// <returns>CRC校验码</returns>
        private byte[] Crc16(byte[] pucFrame, int uslen)
        {
            int i = 0;
            byte[] res = new byte[2] { 0xff, 0xff };
            ushort iIndex;
            while (uslen-- > 0)
            {
                iIndex = (ushort)(res[0] ^ pucFrame[i++]);
                res[0] = (byte)(res[1] ^ aucCRCHi[iIndex]);
                res[1] = aucCRCLo[iIndex];
            }
            return res;
        }
        /// <summary>
        /// 判断CRC校验是否正确
        /// </summary>
        /// <param name="value">要校验的数据</param>
        /// <returns>判断的结果</returns>
        private bool CheckCRC(byte[] value)
        {
            if (value == null) return false;
            if (value.Length <= 2) return false;
            int length = value.Length;
            byte[] buf = new byte[length - 2];
            Array.Copy(value, 0, buf, 0, buf.Length);

            byte[] CRCbuf = Crc16(buf, buf.Length);
            if (CRCbuf[0] == value[length - 2] && CRCbuf[1] == value[length - 1])
            {
                return true;
            }
            return false;

        }

       
        #endregion

5、编写读取拼接方法

       /// <summary>
        /// 发送查询数据命令
        /// </summary>
        /// <param name="slaveld">读取的地址</param>
        /// <param name="functionCode">读取的功能码</param>
        /// <param name="startAddress">读取的起始地址</param>
        /// <param name="count">读取的数据长度</param>
        /// <returns>查询的返回数据 null为查询失败</returns>
        private byte[] ReadData(byte slaveld, byte functionCode, ushort startAddress, ushort count)
        {
            if (CurrentCOM != null)
            {
                //组织读取报文
                byte[] SendCommand = GetDatachangeMsgByteRead(slaveld, functionCode, startAddress, count);
                //发送报文
                CurrentCOM.Write(SendCommand, 0, SendCommand.Length);
                //接受报文
                Thread.Sleep(100);
                //定义一个字节数组buffer 用来接收缓存区的数据
                byte[] buffer = new byte[CurrentCOM.BytesToRead];
                //接受缓存取得数据
                CurrentCOM.Read(buffer, 0, buffer.Length);
                //验证CRC校验
                if (CheckCRC(buffer))
                {
                    return buffer;
                }
            }
            return null;
        }
        /// <summary>
        /// 拼接读取数据报文
        /// </summary>
        /// <param name="slaveld">读取的地址</param>
        /// <param name="functionCode">读取的功能码</param>
        /// <param name="startAddress">读取的起始地址</param>
        /// <param name="count">读取的数据长度</param>
        /// <returns>拼接好的报文</returns>
        private byte[] GetDatachangeMsgByteRead(byte slaveld, byte functionCode, ushort startAddress, ushort count)
        {
            //拼接报文
          //创建字节数组
            byte[] SendCommand = new byte[8];
            //从站地址+功能码+起始高位+起始低位+数量高位+数量低位+CRC校验
            //读取的地址
            SendCommand[0] = slaveld;
            //读取的功能码
            SendCommand[1] = functionCode;
            //一个ushort类型的数可以分为 256*高位+低位
            //对ushort类型的数进行 这个数除以256 得到高位数 这个数对256求余 得到低位数 
            //读取的起始地址
            SendCommand[2] = (byte)(startAddress / 256);
            SendCommand[3] = (byte)(startAddress % 256);
            //读取的数据长度
            SendCommand[4] = (byte)(count / 256);
            SendCommand[5] = (byte)(count % 256);
            //CRC校验
            byte[] crc = Crc16(SendCommand, 6);
            //添加CRC校验
            SendCommand[6] = crc[0];
            SendCommand[7] = crc[1];
            return SendCommand;
        }
        /// <summary>
        /// 发送查询string字符串命令
        /// </summary>
        /// <param name="slaveld">读取的地址</param>
        /// <param name="functionCode">读取的功能码</param>
        /// <param name="startAddress">读取的起始地址</param>
        /// <param name="count">读取的数据长度</param>
        /// <returns>查询的返回数据 null为查询失败</returns>
        private byte[] ReadDataString(byte slaveld, byte functionCode, ushort startAddress, ushort count)
        {
            if (CurrentCOM != null)
            {
                //组织读取报文
                byte[] SendCommand = GetDatachangeMsgByteRead(slaveld, functionCode, startAddress, count);
                //发送报文
                CurrentCOM.Write(SendCommand, 0, SendCommand.Length);
                //接受报文
                Thread.Sleep(300);
                //定义一个字节数组buffer 用来接收缓存区的数据
                byte[] buffer = new byte[CurrentCOM.BytesToRead];
                //接受缓存取得数据
                CurrentCOM.Read(buffer, 0, buffer.Length);
                //验证CRC校验
                if (CheckCRC(buffer))
                {
                    return buffer;
                }
            }
            return null;
        }

6、编写写入拼接方法

      /// <summary>
        /// 拼接写数据布尔类型 和 ushort报文
        /// </summary>
        /// <param name="slaveld">从站地址</param>
        /// <param name="functionCode">写入的功能码 05 06</param>
        /// <param name="startAddress">写入的起始地址</param>
        /// <param name="value">写入的数据</param>
        /// <returns>拼接好的报文</returns>
        private byte[] GetDatachangeMsgByteWrite(byte slaveld, byte functionCode, ushort startAddress, ushort value)
        {

            //拼接报文
            //创建字节数组
            byte[] SendCommand = new byte[8];
            //从站地址+功能码+起始高位+起始低位+数量高位+数量低位+CRC校验
            //写入的地址
            SendCommand[0] = slaveld;
            //写入的功能码
            SendCommand[1] = functionCode;

            //一个ushort类型的数可以分为 256*高位+低位
            //对ushort类型的数进行 这个数除以256 得到高位数 这个数对256求余 得到低位数 
            //写入的起始地址
            SendCommand[2] = (byte)(startAddress / 256);
            SendCommand[3] = (byte)(startAddress % 256);
            //判断写入的功能码
            if (functionCode == 5)
            {
                //写入的是0,布尔值为false
                if (value == 0)
                {
                    SendCommand[4] = 0x00;
                    SendCommand[5] = 0x00;
                }
                //写入的不是0,布尔值为true
                else
                {
                    SendCommand[4] = 0xff;
                    SendCommand[5] = 0x00;
                }
            }
            //转换成16位无符号整数
            else
            {
                
                SendCommand[4] = (byte)(value / 256);
                SendCommand[5] = (byte)(value % 256);
            }

           

            //CRC校验
            byte[] crc = Crc16(SendCommand, 6);

            //添加CRC校验
            SendCommand[6] = crc[0];
            SendCommand[7] = crc[1];

            return SendCommand;
        }

        /// <summary>
        /// 拼接写 short数据报文
        /// </summary>
        /// <param name="slaveld">从站地址</param>
        /// <param name="startAddress">写入的起始地址</param>
        /// <param name="value">写入的数据</param>
        /// <returns>拼接好的报文</returns>
        private byte[] GetDatachangeMsgByteWrite(byte slaveld, ushort startAddress, short value)
        {

            //拼接报文
            //创建字节数组
            byte[] SendCommand = new byte[8];
            //从站地址+功能码+起始高位+起始低位+数量高位+数量低位+CRC校验
            //写入的地址
            SendCommand[0] = slaveld;
            //写入的功能码
            SendCommand[1] = 6;

            //一个ushort类型的数可以分为 256*高位+低位
            //对ushort类型的数进行 这个数除以256 得到高位数 这个数对256求余 得到低位数 
            //写入的起始地址
            SendCommand[2] = (byte)(startAddress / 256);
            SendCommand[3] = (byte)(startAddress % 256);

            byte[] byt = BitConverter.GetBytes(value);

            SendCommand[4] = byt[1];
            SendCommand[5] = byt[0];

            //CRC校验
            byte[] crc = Crc16(SendCommand, 6);

            //添加CRC校验
            SendCommand[6] = crc[0];
            SendCommand[7] = crc[1];

            return SendCommand;
        }

        /// <summary>
        /// 拼接写 char数据报文
        /// </summary>
        /// <param name="slaveld">从站地址</param>
        /// <param name="startAddress">写入的起始地址</param>
        /// <param name="value">写入的数据</param>
        /// <returns>拼接好的报文</returns>
        private byte[] GetDatachangeMsgByteWrite(byte slaveld, ushort startAddress, char  value)
        {

            //拼接报文
            //创建字节数组
            byte[] SendCommand = new byte[8];
            //从站地址+功能码+起始高位+起始低位+数量高位+数量低位+CRC校验
            //写入的地址
            SendCommand[0] = slaveld;
            //写入的功能码
            SendCommand[1] = 6;

            //一个ushort类型的数可以分为 256*高位+低位
            //对ushort类型的数进行 这个数除以256 得到高位数 这个数对256求余 得到低位数 
            //写入的起始地址
            SendCommand[2] = (byte)(startAddress / 256);
            SendCommand[3] = (byte)(startAddress % 256);

            byte[] byt = BitConverter.GetBytes(value);

            SendCommand[4] = byt[1];
            SendCommand[5] = byt[0];

            //CRC校验
            byte[] crc = Crc16(SendCommand, 6);

            //添加CRC校验
            SendCommand[6] = crc[0];
            SendCommand[7] = crc[1];

            return SendCommand;
        }

        /// <summary>
        /// 拼接写16位short数据报文
        /// </summary>
        /// <param name="slaveld">从站地址</param>
        /// <param name="startAddress">写入的起始地址</param>
        /// <param name="count">写入的数据长度</param>
        /// <param name="value">写入的数据</param>
        /// <returns>拼接好的报文</returns>
        private byte[] GetDatachangeMsgByteWrite(byte slaveld, ushort startAddress, ushort count, short[] value)
        {
            //地址、功能码、寄存器起始地址、寄存器个数、要写入数据的字节数、数据、校验码

            //拼接报文
            //创建字节数组集合

            List<byte> SendCommand = new List<byte>();
            //从站地址
            SendCommand.Add(slaveld);
            //功能码
            SendCommand.Add(16);
            //寄存器起始地址的高位
            SendCommand.Add((byte)(startAddress / 256));
            //寄存器起始地址的低位
            SendCommand.Add((byte)(startAddress % 256));
            //寄存器个数的高位
            SendCommand.Add((byte)(count / 256));
            //寄存器个数的低位
            SendCommand.Add((byte)(count % 256));
            //要写入数据的字节数
            SendCommand.Add((byte)(count * 2));
            for (int i = 0; i < value.Length; i++)
            {
                //把16位short型转换成字节数组
                byte[] byt = BitConverter.GetBytes(value[i]);
                //把字节数组中的高低位颠倒
                ReverseBytes16(byt);
                //加到集合中
                SendCommand.AddRange(byt);
            }

            //CRC校验
            byte[] crc = Crc16(SendCommand.ToArray(), SendCommand.Count);
            //CRC校验加到集合中
            SendCommand.AddRange(crc);

            //返回拼接好的字符
            return SendCommand.ToArray();
        }

        /// <summary>
        /// 拼接写16位ushort数据报文
        /// </summary>
        /// <param name="slaveld">从站地址</param>
        /// <param name="startAddress">写入的起始地址</param>
        /// <param name="count">写入的数据长度</param>
        /// <param name="value">写入的数据</param>
        /// <returns>拼接好的报文</returns>
        private byte[] GetDatachangeMsgByteWrite(byte slaveld, ushort startAddress, ushort count, ushort[] value)
        {
            //地址、功能码、寄存器起始地址、寄存器个数、要写入数据的字节数、数据、校验码

            //拼接报文
            //创建字节数组集合

            List<byte> SendCommand = new List<byte>();
            //从站地址
            SendCommand.Add(slaveld);
            //功能码
            SendCommand.Add(16);
            //寄存器起始地址的高位
            SendCommand.Add((byte)(startAddress / 256));
            //寄存器起始地址的低位
            SendCommand.Add((byte)(startAddress % 256));
            //寄存器个数的高位
            SendCommand.Add((byte)(count / 256));
            //寄存器个数的低位
            SendCommand.Add((byte)(count % 256));
            //要写入数据的字节数
            SendCommand.Add((byte)(count * 2));
            for (int i = 0; i < value.Length; i++)
            {
                //把16位ushort型转换成字节数组
                byte[] byt = BitConverter.GetBytes(value[i]);
                //把字节数组中的高低位颠倒
                ReverseBytes16(byt);
                //加到集合中
                SendCommand.AddRange(byt);
            }

            //CRC校验
            byte[] crc = Crc16(SendCommand.ToArray(), SendCommand.Count);
            //CRC校验加到集合中
            SendCommand.AddRange(crc);

            //返回拼接好的字符
            return SendCommand.ToArray();
        }

        /// <summary>
        /// 拼接写16位ushort数据报文
        /// </summary>
        /// <param name="slaveld">从站地址</param>
        /// <param name="functionCode">功能码 15 16</param>
        /// <param name="startAddress">写入的起始地址</param>
        /// <param name="count">写入的数据长度</param>
        /// <param name="value">写入的数据</param>
        /// <returns>拼接好的报文</returns>
        private byte[] GetDatachangeMsgByteWrite(byte slaveld, byte functionCode, ushort startAddress, ushort count, ushort[] value)
        {
            //地址、功能码、寄存器起始地址、寄存器个数、要写入数据的字节数、数据、校验码

            //拼接报文
            //创建字节数组集合

            List<byte> SendCommand = new List<byte>();
            //从站地址
            SendCommand.Add(slaveld);
            //功能码
            SendCommand.Add(functionCode);
            //寄存器起始地址的高位
            SendCommand.Add((byte)(startAddress / 256));
            //寄存器起始地址的低位
            SendCommand.Add((byte)(startAddress % 256));
            if(functionCode==15)
            {
                //声明一个收到数据的个数
                ushort number = (ushort)(count*16);
                //寄存器个数的高位
                SendCommand.Add((byte)(number / 256));
                //寄存器个数的低位
                SendCommand.Add((byte)(number % 256));
                //要写入数据的字节数
                SendCommand.Add((byte)(count * 2));
                for (int i = 0; i < value.Length; i++)
                {

                    SendCommand.Add((byte)(value[i] % 256));
                    SendCommand.Add((byte)(value[i] / 256));
                }

            }
            else
            {
                //寄存器个数的高位
                SendCommand.Add((byte)(count / 256));
                //寄存器个数的低位
                SendCommand.Add((byte)(count % 256));
                //要写入数据的字节数
                SendCommand.Add((byte)(count * 2));
                for (int i = 0; i < value.Length; i++)
                {
                    SendCommand.Add((byte)(value[i] / 256));
                    SendCommand.Add((byte)(value[i] % 256));
                    
                }
            }
            
           

            //CRC校验
            byte[] crc = Crc16(SendCommand.ToArray(), SendCommand.Count);
            //CRC校验加到集合中
            SendCommand.AddRange(crc);

            //返回拼接好的字符
            return SendCommand.ToArray();
        }

        /// <summary>
        /// 拼接写32位int数据报文
        /// </summary>
        /// <param name="slaveld">从站地址</param>
        /// <param name="startAddress">写入的起始地址</param>
        /// <param name="count">写入的数据长度</param>
        /// <param name="value">写入的数据</param>
        /// <returns>拼接好的报文</returns>
        private byte[] GetDatachangeMsgByteWrite(byte slaveld, ushort startAddress, ushort count, int[] value)
        {
            //地址、功能码、寄存器起始地址、寄存器个数、要写入数据的字节数、数据、校验码

            //拼接报文
            //创建字节数组集合

            List<byte> SendCommand = new List<byte>();
            //从站地址
            SendCommand.Add(slaveld);
            //功能码
            SendCommand.Add(16);
            //寄存器起始地址的高位
            SendCommand.Add((byte)(startAddress / 256));
            //寄存器起始地址的低位
            SendCommand.Add((byte)(startAddress % 256));
            //寄存器个数的高位
            SendCommand.Add((byte)(count / 256));
            //寄存器个数的低位
            SendCommand.Add((byte)(count % 256));
            //要写入数据的字节数
            SendCommand.Add((byte)(count*2));
            for (int i = 0; i < value.Length; i++)
            {
                //把32位int型转换成字节数组
                byte[] byt = BitConverter.GetBytes(value[i]);
                //把字节数组中的高低位颠倒
                ReverseBytes32(byt);
                //加到集合中
                SendCommand.AddRange(byt);
            }
           
            //CRC校验
            byte[] crc = Crc16(SendCommand.ToArray(), SendCommand.Count);
            //CRC校验加到集合中
            SendCommand.AddRange(crc);
            
            //返回拼接好的字符
            return SendCommand.ToArray();
        }

        /// <summary>
        /// 拼接写32位uint数据报文
        /// </summary>
        /// <param name="slaveld">从站地址</param>
        /// <param name="startAddress">写入的起始地址</param>
        /// <param name="count">写入的数据长度</param>
        /// <param name="value">写入的数据</param>
        /// <returns>拼接好的报文</returns>
        private byte[] GetDatachangeMsgByteWrite(byte slaveld, ushort startAddress, ushort count, uint[] value)
        {
            //地址、功能码、寄存器起始地址、寄存器个数、要写入数据的字节数、数据、校验码


            //拼接报文
            //创建字节数组集合

            List<byte> SendCommand = new List<byte>();
            //从站地址
            SendCommand.Add(slaveld);
            //功能码
            SendCommand.Add(16);
            //寄存器起始地址的高位
            SendCommand.Add((byte)(startAddress / 256));
            //寄存器起始地址的低位
            SendCommand.Add((byte)(startAddress % 256));
            //寄存器个数的高位
            SendCommand.Add((byte)(count / 256));
            //寄存器个数的低位
            SendCommand.Add((byte)(count % 256));
            //要写入数据的字节数
            SendCommand.Add((byte)(count * 2));
            for (int i = 0; i < value.Length; i++)
            {
                //把32位uint型转换成字节数组
                byte[] byt = BitConverter.GetBytes(value[i]);
                //把字节数组中的高低位颠倒
                ReverseBytes32(byt);
                //加到集合中
                SendCommand.AddRange(byt);
            }

            //CRC校验
            byte[] crc = Crc16(SendCommand.ToArray(), SendCommand.Count);
            //CRC校验加到集合中
            SendCommand.AddRange(crc);

            //返回拼接好的字符
            return SendCommand.ToArray();
        }

        /// <summary>
        /// 拼接写32位float数据报文
        /// </summary>
        /// <param name="slaveld">从站地址</param>
        /// <param name="startAddress">写入的起始地址</param>
        /// <param name="count">写入的数据长度</param>
        /// <param name="value">写入的数据</param>
        /// <returns>拼接好的报文</returns>
        private byte[] GetDatachangeMsgByteWrite(byte slaveld, ushort startAddress, ushort count, float[] value)
        {
            //地址、功能码、寄存器起始地址、寄存器个数、要写入数据的字节数、数据、校验码
            //拼接报文
            //创建字节数组集合

            List<byte> SendCommand = new List<byte>();
            //从站地址
            SendCommand.Add(slaveld);
            //功能码
            SendCommand.Add(16);
            //寄存器起始地址的高位
            SendCommand.Add((byte)(startAddress / 256));
            //寄存器起始地址的低位
            SendCommand.Add((byte)(startAddress % 256));
            //寄存器个数的高位
            SendCommand.Add((byte)(count / 256));
            //寄存器个数的低位
            SendCommand.Add((byte)(count % 256));
            //要写入数据的字节数
            SendCommand.Add((byte)(count * 2));
            for (int i = 0; i < value.Length; i++)
            {
                //把32位float型转换成字节数组
                byte[] byt = BitConverter.GetBytes(value[i]);
                //把字节数组中的高低位颠倒
                ReverseBytes32(byt);
                //加到集合中
                SendCommand.AddRange(byt);
            }
            //CRC校验
            byte[] crc = Crc16(SendCommand.ToArray(), SendCommand.Count);
            //CRC校验加到集合中
            SendCommand.AddRange(crc);

            //返回拼接好的字符
            return SendCommand.ToArray();
        }

        /// <summary>
        /// 拼接写字符串数据报文
        /// </summary>
        /// <param name="slaveld">从站地址</param>
        /// <param name="startAddress">写入的起始地址</param>
        /// <param name="count">写入的数据长度</param>
        /// <param name="value">写入的数据</param>
        /// <returns>拼接好的报文</returns>
        private byte[] GetDatachangeMsgByteWrite(byte slaveld, ushort startAddress, ushort count, char[] value)
        {
            //地址、功能码、寄存器起始地址、寄存器个数、要写入数据的字节数、数据、校验码

            //拼接报文
            //创建字节数组集合

            List<byte> SendCommand = new List<byte>();
            //从站地址
            SendCommand.Add(slaveld);
            //功能码
            SendCommand.Add(16);
            //寄存器起始地址的高位
            SendCommand.Add((byte)(startAddress / 256));
            //寄存器起始地址的低位
            SendCommand.Add((byte)(startAddress % 256));
            //寄存器个数的高位
            SendCommand.Add((byte)(count / 256));
            //寄存器个数的低位
            SendCommand.Add((byte)(count % 256));
            //要写入数据的字节数
            SendCommand.Add((byte)(count * 2));
            for (int i = 0; i < value.Length; i++)
            {
                //把32位int型转换成字节数组
                byte[] byt = BitConverter.GetBytes(value[i]);
                //把字节数组中的高低位颠倒
                ReverseBytes16(byt);
                //加到集合中
                SendCommand.AddRange(byt);
            }

            //CRC校验
            byte[] crc = Crc16(SendCommand.ToArray(), SendCommand.Count);
            //CRC校验加到集合中
            SendCommand.AddRange(crc);

            //返回拼接好的字符
            return SendCommand.ToArray();
        }

        /// <summary>
        /// 拼接写字符串数据报文
        /// </summary>
        /// <param name="slaveld">从站地址</param>
        /// <param name="startAddress">写入的起始地址</param>
        /// <param name="count">写入的数据长度</param>
        /// <returns>拼接好的报文</returns>
        private byte[] GetDatachangeMsgByteWriteString(byte slaveld, ushort startAddress, ushort count)
        {
            //地址、功能码、寄存器起始地址、寄存器个数、要写入数据的字节数、数据、校验码

            //拼接报文
            //创建字节数组集合

            List<byte> SendCommand = new List<byte>();
            //从站地址
            SendCommand.Add(slaveld);
            //功能码
            SendCommand.Add(16);
            //寄存器起始地址的高位
            SendCommand.Add((byte)(startAddress / 256));
            //寄存器起始地址的低位
            SendCommand.Add((byte)(startAddress % 256));
            //寄存器个数的高位
            SendCommand.Add((byte)(count / 256));
            //寄存器个数的低位
            SendCommand.Add((byte)(count % 256));
            //要写入数据的字节数
            SendCommand.Add((byte)(count * 2));
            for (int i = 0,j=0; i < count * 2; i++)
            {
                SendCommand.Add((byte)j);
            }

            //CRC校验
            byte[] crc = Crc16(SendCommand.ToArray(), SendCommand.Count);
            //CRC校验加到集合中
            SendCommand.AddRange(crc);

            //返回拼接好的字符
            return SendCommand.ToArray();
        }

7、编写读取方法

      #region 读取数据

        /// <summary>
        /// 读取bool数据结果
        /// </summary>
        /// <param name="slaveld">读取从站的地址</param>
        /// <param name="functionCode">读取的功能码 值为 01 02 03 04  </param>
        /// <param name="startAddress">读取的起始地址 偏移地址  读取的地址从0开始</param>
        /// <param name="count">读取的数据长度</param>
        /// <returns>读取到的值  返回null则读取失败</returns>
        public bool[] ReadBool(byte slaveld, byte functionCode, ushort startAddress, ushort count)
        {
            if (functionCode == 2 || functionCode == 1 || functionCode == 3 || functionCode == 4)
            {
                //调用函数来发送查询命令
                byte[] buffer = ReadData(slaveld, functionCode, startAddress, count);
                //声明一个收到数据的个数
                ushort number;
                //表示一个收到数据有多少位
                ushort count1;
                //判断是读取位还是读取字的
                if (functionCode == 2 || functionCode == 1)
                {
                    //表示读取的是位
                    if ((count % 8) == 0)
                    {
                        number = (ushort)(count / 8);
                    }
                    else
                    {
                        number = (ushort)((count / 8) + 1);
                    }
                    count1 = count;
                }
                else
                {
                    //表示读取的是字
                    //字的长度有两位组成
                    number = (ushort)(count * 2);
                    count1 = (ushort)(number * 8);
                }
                //验证报文
                if (buffer != null)
                {
                    //判断长度是否正常
                    if (buffer.Length == 5 + number)
                    {
                        //判断地址和功能码
                        if (buffer[0] == slaveld && buffer[1] == functionCode)
                        {
                            //解析报文
                            char[] chk = new char[8] { '0', '0', '0', '0', '0', '0', '0', '0' };
                            //接受数据
                            byte[] result = new byte[number];
                            //获取数据,去除报头和校验
                            Array.Copy(buffer, 3, result, 0, number);
                            if (functionCode == 4 || functionCode == 3)
                            {
                                //高低地址交换
                                ReverseBytes16(result);
                            }
                            //声明一个字符数组,用来接受转换后的二进制
                            char[] returns = new char[count1];
                            char[] intermediate;
                            for (int i = 0; i < result.Length; i++)
                            {
                                //把收到的数据转换成二进制字符串
                                intermediate = Convert.ToString(result[i], 2).ToArray();
                                //反转字符串
                                Array.Reverse(intermediate);
                                //把收到的每个数据都加载到声明的字符数组中
                                Array.Copy(intermediate, 0, returns, i * 8, intermediate.Length);
                                //补齐收到数据中的零
                                if (i * 8 + 8 < count1)
                                {
                                    Array.Copy(chk, 0, returns, i * 8 + intermediate.Length, 8 - intermediate.Length);

                                }
                                else if (i * 8 + intermediate.Length < count1)
                                {
                                    Array.Copy(chk, 0, returns, i * 8 + intermediate.Length, count1 - (i * 8 + intermediate.Length));
                                }
                            }
                            //把收到的字符数组转换成布尔数组并返回
                            return CharacterToBoolean(returns);
                        }
                    }
                }
            }
            //解析失败返回 nill
            return null;
        }
        /// <summary>
        /// 读取浮点数
        /// </summary>
        /// <param name="slaveld">从站地址</param>
        /// <param name="functionCode">功能码 03 04 </param>
        /// <param name="startAddress">读取的起始地址 偏移地址</param>
        /// <param name="count">读取数据的个数</param>
        /// <returns>读取到的值  返回null则读取失败</returns>
        public float[] ReadFloat(byte slaveld, byte functionCode, ushort startAddress, ushort count)
        {
            if (functionCode == 3 || functionCode == 4)
            {
                //调用函数来发送查询命令
                byte[] buffer = ReadData(slaveld, functionCode, startAddress, (ushort)(count * 2));
                //声明一个收到数据的个数
                ushort number = (ushort)(count * 4);
                //验证报文
                if (buffer != null)
                {
                    if (buffer.Length == 5 + number)
                    {
                        if (buffer[0] == slaveld && buffer[1] == functionCode)
                        {
                            //解析报文
                            //接受数据
                            byte[] result = new byte[number];
                            //获取数据,去除报头和校验
                            Array.Copy(buffer, 3, result, 0, number);
                            //高低地址交换
                            ReverseBytes32(result);
                            //声明一个用来返回结果的数组
                            float[] returns = new float[count];
                            float intermediate;
                            for (int i = 0; i * 4 < result.Length; i++)
                            {
                                //转换成32位浮点数
                                intermediate = BitConverter.ToSingle(result, i * 4);
                                returns[i] = intermediate;
                            }
                            //返回结果
                            return returns;
                        }
                    }
                }
            }
            //解析失败返回 nill
            return null;
        }
        /// <summary>
        /// 读取32位整数
        /// </summary>
        /// <param name="slaveld">从站地址</param>
        /// <param name="functionCode">功能码 03 04 </param>
        /// <param name="startAddress">读取的起始地址 偏移地址</param>
        /// <param name="count">读取数据的个数</param>
        /// <returns>读取到的值  返回null则读取失败</returns>
        public int[] ReadInt(byte slaveld, byte functionCode, ushort startAddress, ushort count)
        {
            if (functionCode == 3 || functionCode == 4)
            {
                //调用函数来发送查询命令
                byte[] buffer = ReadData(slaveld, functionCode, startAddress, (ushort)(count * 2));
                //声明一个收到数据的个数
                ushort number = (ushort)(count * 4);
                //验证报文
                if (buffer != null)
                {
                    if (buffer.Length == 5 + number)
                    {
                        if (buffer[0] == slaveld && buffer[1] == functionCode)
                        {
                            //解析报文
                            //接受数据
                            byte[] result = new byte[number];
                            //获取数据,去除报头和校验
                            Array.Copy(buffer, 3, result, 0, number);
                            //高低地址交换
                            ReverseBytes32(result);
                            //声明一个用来返回结果的数组
                            int[] returns = new int[count];
                            int intermediate;
                            for (int i = 0; i * 4 < result.Length; i++)
                            {
                                //转换成32位整数
                                intermediate = BitConverter.ToInt32(result, i * 4);
                                returns[i] = intermediate;
                            }
                            //返回结果
                            return returns;
                        }
                    }
                }
            }
            //解析失败返回 nill
            return null;
        }
        /// <summary>
        /// 读取32位无符号整数
        /// </summary>
        /// <param name="slaveld">从站地址</param>
        /// <param name="functionCode">功能码 03 04 </param>
        /// <param name="startAddress">读取的起始地址 偏移地址</param>
        /// <param name="count">读取数据的个数</param>
        /// <returns>读取到的值  返回null则读取失败</returns>
        public uint[] ReadUint(byte slaveld, byte functionCode, ushort startAddress, ushort count)
        {
            if (functionCode == 3 || functionCode == 4)
            {
                //调用函数来发送查询命令
                byte[] buffer = ReadData(slaveld, functionCode, startAddress, (ushort)(count * 2));
                //声明一个收到数据的个数
                ushort number = (ushort)(count * 4);
                //验证报文
                if (buffer != null)
                {
                    if (buffer.Length == 5 + number)
                    {
                        if (buffer[0] == slaveld && buffer[1] == functionCode)
                        {
                            //解析报文
                            //接受数据
                            byte[] result = new byte[number];
                            //获取数据,去除报头和校验
                            Array.Copy(buffer, 3, result, 0, number);
                            //高低地址交换
                            ReverseBytes32(result);
                            //声明一个用来返回结果的数组
                            uint[] returns = new uint[count];
                            uint intermediate;
                            for (int i = 0; i * 4 < result.Length; i++)
                            {
                                //转换成32位无符号整数
                                intermediate = BitConverter.ToUInt32(result, i * 4);
                                returns[i] = intermediate;
                            }
                            //返回结果
                            return returns;
                        }
                    }
                }
            }
            //解析失败返回 nill
            return null;
        }
        /// <summary>
        /// 读取16位整数
        /// </summary>
        /// <param name="slaveld">从站地址</param>
        /// <param name="functionCode">功能码 03 04 </param>
        /// <param name="startAddress">读取的起始地址 偏移地址</param>
        /// <param name="count">读取数据的个数</param>
        /// <returns>读取到的值  返回null则读取失败</returns>
        public short[] ReadShore(byte slaveld, byte functionCode, ushort startAddress, ushort count)
        {
            if (functionCode == 3 || functionCode == 4)
            {
                //调用函数来发送查询命令
                byte[] buffer = ReadData(slaveld, functionCode, startAddress, count);
                //声明一个收到数据的个数
                ushort number = (ushort)(count * 2);
                //验证报文
                if (buffer != null)
                {
                    if (buffer.Length == 5 + number)
                    {
                        if (buffer[0] == slaveld && buffer[1] == functionCode)
                        {
                            //解析报文
                            //接受数据
                            byte[] result = new byte[number];
                            //获取数据,去除报头和校验
                            Array.Copy(buffer, 3, result, 0, number);
                            //高低地址交换
                            ReverseBytes16(result);
                            //声明一个用来返回结果的数组
                            short[] returns = new short[count];
                            short intermediate;
                            for (int i = 0; i * 2 < result.Length; i++)
                            {
                                //转换成16位整数
                                intermediate = BitConverter.ToInt16(result, i * 2);
                                returns[i] = intermediate;
                            }
                            //返回结果
                            return returns;
                        }
                    }
                }
            }
            //解析失败返回 nill
            return null;
        }
        /// <summary>
        /// 读取16位无符号整数
        /// </summary>
        /// <param name="slaveld">从站地址</param>
        /// <param name="functionCode">功能码 03 04 </param>
        /// <param name="startAddress">读取的起始地址 偏移地址</param>
        /// <param name="count">读取数据的个数</param>
        /// <returns>读取到的值  返回null则读取失败</returns>
        public ushort[] ReadUshore(byte slaveld, byte functionCode, ushort startAddress, ushort count)
        {
            if (functionCode == 3 || functionCode == 4)
            {
                //调用函数来发送查询命令
                byte[] buffer = ReadData(slaveld, functionCode, startAddress, count);
                //声明一个收到数据的个数
                ushort number = (ushort)(count * 2);
                //验证报文
                if (buffer != null)
                {
                    if (buffer.Length == 5 + number)
                    {
                        if (buffer[0] == slaveld && buffer[1] == functionCode)
                        {
                            //解析报文
                            //接受数据
                            byte[] result = new byte[number];
                            //获取数据,去除报头和校验
                            Array.Copy(buffer, 3, result, 0, number);
                            //高低地址交换
                            ReverseBytes16(result);
                            //声明一个用来返回结果的数组
                            ushort[] returns = new ushort[count];
                            ushort intermediate;
                            for (int i = 0; i * 2 < result.Length; i++)
                            {
                                //转换成16位无符号整数
                                intermediate = BitConverter.ToUInt16(result, i * 2);
                                returns[i] = intermediate;
                            }
                            //返回结果
                            return returns;
                        }
                    }
                }
            }
            //解析失败返回 nill
            return null;
        }

        /// <summary>
        /// 读取字符串 格式是ASCII 不能表示中文
        /// </summary>
        /// <param name="slaveld">从站地址</param>
        /// <param name="functionCode">功能码 03 04 </param>
        /// <param name="startAddress">读取的起始地址 偏移地址</param>
        /// <param name="count">读取字符的个数 </param>
        /// <returns>读取到的值  返回null则读取失败</returns>
        public string ReadStringASCII(byte slaveld, byte functionCode, ushort startAddress, ushort count)
        {
            if (functionCode == 3 || functionCode == 4)
            {
                //调用函数来发送查询命令
                byte[] buffer = ReadDataString(slaveld, functionCode, startAddress, (ushort)(count));
                //声明一个收到数据的个数
                ushort number = (ushort)(count * 2);
                //验证报文
                if (buffer != null)
                {
                    if (buffer.Length == 5 + number)
                    {
                        if (buffer[0] == slaveld && buffer[1] == functionCode)
                        {
                            //解析报文
                            //接受数据
                            byte[] result = new byte[number];
                            //获取数据,去除报头和校验
                            Array.Copy(buffer, 3, result, 0, number);
                            //声明字符串
                            string intermediate;
                            //把收到的字节数组转换成字符串
                            intermediate = Encoding.ASCII.GetString(result, 0, result.Length);
                            //返回结果
                            return intermediate;
                        }
                    }
                }
            }
            //解析失败返回 nill
            return null;
        }
        /// <summary>
        /// 读取字符串 格式是Unicode 可以表示中文
        /// </summary>
        /// <param name="slaveld">从站地址</param>
        /// <param name="functionCode">功能码 03 04 </param>
        /// <param name="startAddress">读取的起始地址 偏移地址</param>
        /// <param name="count">读取字符的个数 </param>
        /// <returns>读取到的值  返回null则读取失败</returns>
        public string ReadStringUnicode(byte slaveld, byte functionCode, ushort startAddress, ushort count)
        {
            if (functionCode == 3 || functionCode == 4)
            {
                //调用函数来发送查询命令
                byte[] buffer = ReadDataString(slaveld, functionCode, startAddress, (ushort)(count));
                //声明一个收到数据的个数
                ushort number = (ushort)(count * 2);
                //验证报文
                if (buffer != null)
                {
                    if (buffer.Length == 5 + number)
                    {
                        if (buffer[0] == slaveld && buffer[1] == functionCode)
                        {
                            //解析报文
                            //接受数据
                            byte[] result = new byte[number];
                            //获取数据,去除报头和校验
                            Array.Copy(buffer, 3, result, 0, number);
                            //高低地址交换
                            ReverseBytes16(result);
                            //声明字符串
                            string intermediate;
                            //把收到的字节数组转换成字符串
                            intermediate = Encoding.Unicode.GetString(result, 0, result.Length);
                            //返回结果
                            return intermediate;
                        }
                    }
                }
            }
            //解析失败返回 nill
            return null;
        }

        #endregion

8、编写写入方法

  #region 写入数据
        /// <summary>
        /// 写入16位无符号整数
        /// </summary>
        /// <param name="slaveld">从站地址</param>
        /// <param name="startAddress">写入的起始地址 偏移地址</param>
        /// <param name="value">写入的数据</param>
        /// <returns>写入的结果 成功返回true</returns>
        public bool Write16(byte slaveld, ushort startAddress, ushort value)
        {
            //创建字节数组
            byte[] SendCommand = GetDatachangeMsgByteWrite(slaveld,6, startAddress, value);
            //发送报文
            CurrentCOM.Write(SendCommand, 0, SendCommand.Length);
            //接受报文
            Thread.Sleep(100);
            //定义一个字节数组buffer 用来接收缓存区的数据
            byte[] buffer = new byte[CurrentCOM.BytesToRead];
            //接受缓存取得数据
            CurrentCOM.Read(buffer, 0, buffer.Length);
            if ( buffer[1] == 6)
            {
                return true;
            }
            //写入失败返回 false
            return false;

            
        }
        /// <summary>
        /// 写入16位整数
        /// </summary>
        /// <param name="slaveld">从站地址</param>
        /// <param name="startAddress">写入的起始地址 偏移地址</param>
        /// <param name="value">写入的数据</param>
        /// <returns>写入的结果 成功返回true</returns>
        public bool Write16(byte slaveld, ushort startAddress, short  value)
        {
            //创建字节数组
            byte[] SendCommand = GetDatachangeMsgByteWrite(slaveld,  startAddress, value);
            //发送报文
            CurrentCOM.Write(SendCommand, 0, SendCommand.Length);
            //接受报文
            Thread.Sleep(100);
            //定义一个字节数组buffer 用来接收缓存区的数据
            byte[] buffer = new byte[CurrentCOM.BytesToRead];
            //接受缓存取得数据
            CurrentCOM.Read(buffer, 0, buffer.Length);
            if (buffer[1] == 6)
            {
                return true;
            }
            //写入失败返回 false
            return false;
        }

        /// <summary>
        /// 写入多个16位整数
        /// </summary>
        /// <param name="slaveld">从站地址</param>
        /// <param name="startAddress">写入的起始地址 偏移地址</param>
        /// <param name="count">写入的个数</param>
        /// <param name="value">写入的数据</param>
        /// <returns>写入的结果 成功返回true</returns>
        public bool Write16(byte slaveld, ushort startAddress, ushort count, short[] value)
        {
            //创建字节数组
            byte[] SendCommand = GetDatachangeMsgByteWrite(slaveld, startAddress, count, value);
            //发送报文
            CurrentCOM.Write(SendCommand, 0, SendCommand.Length);
            //接受报文
            Thread.Sleep(100);
            //定义一个字节数组buffer 用来接收缓存区的数据
            byte[] buffer = new byte[CurrentCOM.BytesToRead];
            //接受缓存取得数据
            CurrentCOM.Read(buffer, 0, buffer.Length);
            if (buffer[1] == 16)
            {
                return true;
            }
            //写入失败返回 false
            return false;
        }
        /// <summary>
        /// 写入多个16位无符号整数
        /// </summary>
        /// <param name="slaveld">从站地址</param>
        /// <param name="startAddress">写入的起始地址 偏移地址</param>
        /// <param name="count">写入的个数</param>
        /// <param name="value">写入的数据</param>
        /// <returns>写入的结果 成功返回true</returns>
        public bool Write16(byte slaveld, ushort startAddress, ushort count, ushort[] value)
        {
            //创建字节数组
            byte[] SendCommand = GetDatachangeMsgByteWrite(slaveld, startAddress, count, value);
            //发送报文
            CurrentCOM.Write(SendCommand, 0, SendCommand.Length);
            //接受报文
            Thread.Sleep(100);
            //定义一个字节数组buffer 用来接收缓存区的数据
            byte[] buffer = new byte[CurrentCOM.BytesToRead];
            //接受缓存取得数据
            CurrentCOM.Read(buffer, 0, buffer.Length);
            if (buffer[1] == 16)
            {
                return true;
            }
            //写入失败返回 false
            return false;
        }


        /// <summary>
        /// 写入32位整数
        /// </summary>
        /// <param name="slaveld">从站地址</param>
        /// <param name="startAddress">写入的起始地址 偏移地址</param>
        /// <param name="value">写入的数据</param>
        /// <returns>写入的结果 成功返回true</returns>
        public bool Write32(byte slaveld, ushort startAddress, int  value)
        {
            
            //创建字节数组
            byte[] SendCommand = GetDatachangeMsgByteWrite(slaveld,startAddress,2,new int[]{value} );
            //发送报文
            CurrentCOM.Write(SendCommand, 0, SendCommand.Length);
            //接受报文
            Thread.Sleep(100);
            //定义一个字节数组buffer 用来接收缓存区的数据
            byte[] buffer = new byte[CurrentCOM.BytesToRead];
            //接受缓存取得数据
            CurrentCOM.Read(buffer, 0, buffer.Length);
            if (buffer[1] == 16)
            {
                return true;
            }
            //写入失败返回 false
            return false;
        }

        /// <summary>
        /// 写入32位无符号整数
        /// </summary>
        /// <param name="slaveld">从站地址</param>
        /// <param name="startAddress">写入的起始地址 偏移地址</param>
        /// <param name="value">写入的数据</param>
        /// <returns>写入的结果 成功返回true</returns>
        public bool Write32(byte slaveld, ushort startAddress, uint value)
        {
            //创建字节数组
            byte[] SendCommand = GetDatachangeMsgByteWrite(slaveld, startAddress, 2, new uint[] { value });
            //发送报文
            CurrentCOM.Write(SendCommand, 0, SendCommand.Length);
            //接受报文
            Thread.Sleep(100);
            //定义一个字节数组buffer 用来接收缓存区的数据
            byte[] buffer = new byte[CurrentCOM.BytesToRead];
            //接受缓存取得数据
            CurrentCOM.Read(buffer, 0, buffer.Length);
            if (buffer[1] == 16)
            {
                return true;
            }
            //写入失败返回 false
            return false;
        }

        /// <summary>
        /// 写入多个32位无符号整数
        /// </summary>
        /// <param name="slaveld">从站地址</param>
        /// <param name="startAddress">写入的起始地址 偏移地址</param>
        /// <param name="count">写入的个数</param>
        /// <param name="value">写入的数据</param>
        /// <returns>写入的结果 成功返回true</returns>
        public bool Write32(byte slaveld, ushort startAddress, ushort count, uint[] value)
        {
            //创建字节数组
            byte[] SendCommand = GetDatachangeMsgByteWrite(slaveld, startAddress, (ushort)(count*2), value);
            //发送报文
            CurrentCOM.Write(SendCommand, 0, SendCommand.Length);
            //接受报文
            Thread.Sleep(100);
            //定义一个字节数组buffer 用来接收缓存区的数据
            byte[] buffer = new byte[CurrentCOM.BytesToRead];
            //接受缓存取得数据
            CurrentCOM.Read(buffer, 0, buffer.Length);
            if (buffer[1] == 16)
            {
                return true;
            }
            //写入失败返回 false
            return false;
        }

        /// <summary>
        /// 写入多个32位整数
        /// </summary>
        /// <param name="slaveld">从站地址</param>
        /// <param name="startAddress">写入的起始地址 偏移地址</param>
        /// <param name="count">写入的个数</param>
        /// <param name="value">写入的数据</param>
        /// <returns>写入的结果 成功返回true</returns>
        public bool Write32(byte slaveld, ushort startAddress, ushort count, int[] value)
        {
            //创建字节数组
            byte[] SendCommand = GetDatachangeMsgByteWrite(slaveld, startAddress, (ushort)(count * 2), value);
            //发送报文
            CurrentCOM.Write(SendCommand, 0, SendCommand.Length);
            //接受报文
            Thread.Sleep(100);
            //定义一个字节数组buffer 用来接收缓存区的数据
            byte[] buffer = new byte[CurrentCOM.BytesToRead];
            //接受缓存取得数据
            CurrentCOM.Read(buffer, 0, buffer.Length);
            if (buffer[1] == 16)
            {
                return true;
            }
            //写入失败返回 false
            return false;
        }

        /// <summary>
        /// 写入32位浮点数
        /// </summary>
        /// <param name="slaveld">从站地址</param>
        /// <param name="startAddress">写入的起始地址 偏移地址</param>
        /// <param name="value">写入的数据  </param>
        /// <returns>写入的结果 成功返回true</returns>
        public bool Write32(byte slaveld, ushort startAddress, float  value)
        {
            //创建字节数组
            byte[] SendCommand = GetDatachangeMsgByteWrite(slaveld, startAddress, 2, new float[] { value });
            //发送报文
            CurrentCOM.Write(SendCommand, 0, SendCommand.Length);
            //接受报文
            Thread.Sleep(100);
            //定义一个字节数组buffer 用来接收缓存区的数据
            byte[] buffer = new byte[CurrentCOM.BytesToRead];
            //接受缓存取得数据
            CurrentCOM.Read(buffer, 0, buffer.Length);
            if (buffer[1] == 16)
            {
                return true;
            }
            //写入失败返回 false
            return false;
        }

        /// <summary>
        /// 写入多个32位浮点数
        /// </summary>
        /// <param name="slaveld">从站地址</param>
        /// <param name="startAddress">写入的起始地址 偏移地址</param>
        /// <param name="count">写入的个数</param>
        /// <param name="value">写入的数据</param>
        /// <returns>写入的结果 成功返回true</returns>
        public bool Write32(byte slaveld, ushort startAddress, ushort count, float[] value)
        {
            //创建字节数组
            byte[] SendCommand = GetDatachangeMsgByteWrite(slaveld, startAddress, (ushort)(count * 2), value);
            //发送报文
            CurrentCOM.Write(SendCommand, 0, SendCommand.Length);
            //接受报文
            Thread.Sleep(100);
            //定义一个字节数组buffer 用来接收缓存区的数据
            byte[] buffer = new byte[CurrentCOM.BytesToRead];
            //接受缓存取得数据
            CurrentCOM.Read(buffer, 0, buffer.Length);
            if (buffer[1] == 16)
            {
                return true;
            }
            //写入失败返回 false
            return false;
        }

        /// <summary>
        /// 写入字符串
        /// </summary>
        /// <param name="slaveld">从站地址</param>
        /// <param name="startAddress">写入的起始地址 偏移地址</param>
        /// <param name="value">写入的数据  </param>
        /// <returns>写入的结果 成功返回true</returns>
        public bool WriteString(byte slaveld, ushort startAddress, string  value)
        {
            //清空以前数据
            byte[] by =  GetDatachangeMsgByteWriteString(slaveld, startAddress, 64);
            //发送报文
            CurrentCOM.Write(by, 0, by.Length);
            //接受报文
            Thread.Sleep(100);
            //定义一个字节数组buffer 用来接收缓存区的数据
            byte[] buffers = new byte[CurrentCOM.BytesToRead];
            //接受缓存取得数据
            CurrentCOM.Read(buffers, 0, buffers.Length);
            //字符串转成字符数组
            char[] ch = value.ToCharArray();
            //创建字节数组
            byte[] SendCommand = GetDatachangeMsgByteWrite(slaveld, startAddress, (ushort)(ch.Length), ch);
            //发送报文
            CurrentCOM.Write(SendCommand, 0, SendCommand.Length);
            //接受报文
            Thread.Sleep(100);
            //定义一个字节数组buffer 用来接收缓存区的数据
            byte[] buffer = new byte[CurrentCOM.BytesToRead];
            //接受缓存取得数据
            CurrentCOM.Read(buffer, 0, buffer.Length);
            if (buffer[1] == 16)
            {
                return true;
            }
            //写入失败返回 false
            return false;
        }

        /// <summary>
        /// 写入单个布尔值
        /// </summary>
        /// <param name="slaveld">从站地址</param>
        /// <param name="functionCode">功能码 功能码为05 06 </param>
        /// <param name="startAddress">写入偏移地址</param>
        /// <param name="value">写入数据</param>
        /// <returns>写入是否成功 成功返回true</returns>
        public bool WriteBool(byte slaveld, byte functionCode,ushort startAddress, ushort value)
        {
            //创建字节数组
            byte[] SendCommand = GetDatachangeMsgByteWrite(slaveld,functionCode,startAddress,value);
            //发送报文
            CurrentCOM.Write(SendCommand, 0, SendCommand.Length);
            //接受报文
           Thread.Sleep(100);
            //定义一个字节数组buffer 用来接收缓存区的数据
            byte[] buffer = new byte[CurrentCOM.BytesToRead];
            //接受缓存取得数据
           CurrentCOM.Read(buffer, 0, buffer.Length);
            if(buffer[1]==5|| buffer[1] == 6)
            {
                return true;
            }
            //写入失败返回 false
            return false;
        }

        /// <summary>
        /// 写入多个布尔值
        /// </summary>
        /// <param name="slaveld">从站地址</param>
        /// <param name="functionCode">功能码 功能码为15 16 </param>
        /// <param name="startAddress">写入偏移地址</param>
        /// <param name="count">写入数据的个数</param>
        /// <param name="value">写入数据</param>
        /// <returns>写入是否成功 成功返回true</returns>
        public bool WriteBool(byte slaveld, byte functionCode, ushort startAddress, ushort count, ushort[] value)
        {
            //创建字节数组
            byte[] SendCommand = GetDatachangeMsgByteWrite(slaveld, functionCode, startAddress, count,value );
            //发送报文
            CurrentCOM.Write(SendCommand, 0, SendCommand.Length);
            //接受报文
            Thread.Sleep(100);
            //定义一个字节数组buffer 用来接收缓存区的数据
            byte[] buffer = new byte[CurrentCOM.BytesToRead];
            //接受缓存取得数据
            CurrentCOM.Read(buffer, 0, buffer.Length);
            if (buffer[1] == 15 || buffer[1] == 16)
            {
                return true;
            }
            //写入失败返回 false
            return false;
        }

        #endregion

三、调用类库

1、打开关闭串口

//引入名称空间
using MCGSModbus;
 //声明类库实例
 MCGSModbusRTU MCGSModbus = null;
 //创建MCGSRTU通讯对象
 MCGSModbus = new MCGSModbusRTU();

 //打开串口
 MCGSModbus.OpenCOM(COMPortComboBox.Text, Convert.ToInt32(BaudRateComboBox.Text), ParityBitComboBox.Text, Convert.ToInt32(DataBitsComboBox.Text), Convert.ToInt32(StopBitComboBox.Text));
 //关闭串口
 MCGSModbus.CloseCOM();

2、读取数据

   //读取数据
        private void ReadButton_Click(object sender, EventArgs e)
        {
            mark = true;
            //数据转换
            DataParsing(FunctionCodeComboBox.Text, OffsetTextBox.Text, NumberTextBox.Text);
            if (mark)
            {
                    try
                    {

                        int a;
                        switch (TypeComboBox.Text)
                        {
                            case "位":
                                {
                                    bool[] accept = MCGSModbus.ReadBool(slaveld, functionCode, startAddress, count);
                                    a = startAddress + 1;
                                    if (accept != null)
                                    {
                                        for (int i = 0; i < accept.Length; i++)
                                        {
                                            DataTextBox.Text += (a++) + ": " + accept[i] + "  ";

                                            if (i!=0&&i % 7 == 0)
                                            {
                                                //显示数据控件换行
                                                DataTextBox.Text += "\r\n";
                                            }
                                        }
                                        
                                        ReadTipLabel.Text = "读取成功";
                                    }
                                    else
                                    {
                                        ReadTipLabel.Text = "读取失败";
                                        return;
                                    }

                                }

                                break;

                            case "16位整型":
                                {
                                    short[] accept = MCGSModbus.ReadShore(slaveld, functionCode, startAddress, count);
                                    a = startAddress + 1;
                                    if (accept != null)
                                    {
                                        for (int i = 0; i < accept.Length; i++)
                                        {
                                            DataTextBox.Text += (a++) + ": " + accept[i] + "  ";

                                            if (i != 0 && i % 7 == 0)
                                            {
                                                //显示数据控件换行
                                                DataTextBox.Text += "\r\n";
                                            }
                                        }

                                        ReadTipLabel.Text = "读取成功";
                                    }
                                    else
                                    {
                                        ReadTipLabel.Text = "读取失败";
                                        return;
                                    }
                                }
                               


                                break;
                            case "16位无符号整型":
                                {
                                    ushort[] accept = MCGSModbus.ReadUshore(slaveld, functionCode, startAddress, count);
                                    a = startAddress + 1;
                                    if (accept != null)
                                    {
                                        for (int i = 0; i < accept.Length; i++)
                                        {
                                            DataTextBox.Text += (a++) + ": " + accept[i] + "  ";

                                            if (i != 0 && i % 7 == 0)
                                            {
                                                //显示数据控件换行
                                                DataTextBox.Text += "\r\n";
                                            }
                                        }

                                        ReadTipLabel.Text = "读取成功";
                                    }
                                    else
                                    {
                                        ReadTipLabel.Text = "读取失败";
                                        return;
                                    }
                                }

                                break;
                            case "32位整型":
                                {
                                    int[] accept = MCGSModbus.ReadInt(slaveld, functionCode, startAddress, count);
                                    a = startAddress + 1;
                                    if (accept != null)
                                    {
                                        for (int i = 0; i < accept.Length; i++)
                                        {
                                            DataTextBox.Text += a + ": " + accept[i] + "  ";
                                            a += 2;
                                            if (i != 0 && i % 7 == 0)
                                            {
                                                //显示数据控件换行
                                                DataTextBox.Text += "\r\n";
                                            }
                                        }

                                        ReadTipLabel.Text = "读取成功";
                                    }
                                    else
                                    {
                                        ReadTipLabel.Text = "读取失败";
                                        return;
                                    }
                                }
                               
                                break;

                            case "32位无符号整型":
                                {
                                    uint[] accept = MCGSModbus.ReadUint(slaveld, functionCode, startAddress, count);
                                    a = startAddress + 1;
                                    if (accept != null)
                                    {
                                        for (int i = 0; i < accept.Length; i++)
                                        {
                                            DataTextBox.Text += a + ": " + accept[i] + "  ";
                                            a += 2;
                                            if (i != 0 && i % 7 == 0)
                                            {
                                                //显示数据控件换行
                                                DataTextBox.Text += "\r\n";
                                            }
                                        }

                                        ReadTipLabel.Text = "读取成功";
                                    }
                                    else
                                    {
                                        ReadTipLabel.Text = "读取失败";
                                        return;
                                    }
                                }

                                break;
                            case "浮点型":
                                {
                                    float[] accept = MCGSModbus.ReadFloat(slaveld, functionCode, startAddress, count);
                                    a = startAddress + 1;
                                    if (accept != null)
                                    {
                                        for (int i = 0; i < accept.Length; i++)
                                        {
                                            DataTextBox.Text += a + ": " + accept[i] + "  ";
                                            a += 2;
                                            if (i != 0 && i % 7 == 0)
                                            {
                                                //显示数据控件换行
                                                DataTextBox.Text += "\r\n";
                                            }
                                        }

                                        ReadTipLabel.Text = "读取成功";
                                    }
                                    else
                                    {
                                        ReadTipLabel.Text = "读取失败";
                                        return;
                                    }
                                }


                                break;
                            case "字符串":
                                {
                                    string  accept = MCGSModbus.ReadStringUnicode(slaveld, functionCode, startAddress, count);
                                    a = startAddress + 1;
                                    if (accept != null)
                                    {
                                        DataTextBox.Text += a + ": " + accept + " ";
                                        
                                        ReadTipLabel.Text = "读取成功";
                                    }
                                    else
                                    {
                                        ReadTipLabel.Text = "读取失败";
                                        return;
                                    }
                                }

                                break;
                            default:

                                break;
                        }
                        //显示数据控件换行
                        DataTextBox.Text += "\r\n\r\n";
                        //设置显示数据控件的光标在末尾
                        this.DataTextBox.SelectionStart = this.DataTextBox.Text.Length;
                        //跳到光标所在位置
                        this.DataTextBox.ScrollToCaret();

                    }
                    catch
                    {

                        ReadTipLabel.Text = "读取失败";
                    }
               
            }

        }

3、写入数据

 //写入单个数据
        private void WriteDataButton_Click(object sender, EventArgs e)
        {
            mark = true;
            DataParsing(FunctionCodeComboBox1.Text, OffsetTextBox1.Text);
            if (mark)
            {
                try
                {

                    switch (TypeComboBox1.Text)
                    {
                        case "位":
                            {
                                ushort value;

                                try
                                {
                                    value = Convert.ToUInt16(WriteDataTextBox.Text);
                                }
                                catch 
                                {
                                    MessageBox.Show("数据错误");
                                    return;
                                }

                                try
                                {
                                    
                                    if (MCGSModbus.WriteBool(slaveld, functionCode, startAddress, value))
                                    {
                                        WriteSignLabel.Text = "写入成功";
                                    }
                                    else
                                    {
                                        WriteSignLabel.Text = "写入失败";
                                    }

                                  
                                }
                                catch 
                                {
                                    WriteSignLabel.Text = "写入失败";

                                }
                            }
                           
                               
                              

                            break;

                        case "16位整型":
                            {
                                short  value;

                                try
                                {
                                    value = Convert.ToInt16(WriteDataTextBox.Text);
                                }
                                catch
                                {
                                    MessageBox.Show("数据错误");
                                    return;
                                }

                                try
                                {

                                    if (MCGSModbus.Write16(slaveld, startAddress, value))
                                    {
                                        WriteSignLabel.Text = "写入成功";
                                    }
                                    else
                                    {
                                        WriteSignLabel.Text = "写入失败";
                                    }


                                }
                                catch
                                {
                                    WriteSignLabel.Text = "写入失败";

                                }
                            }




                            break;
                        case "16位无符号整型":
                            {
                                ushort value;

                                try
                                {
                                    value = Convert.ToUInt16(WriteDataTextBox.Text);
                                }
                                catch
                                {
                                    MessageBox.Show("数据错误");
                                    return;
                                }

                                try
                                {

                                    if (MCGSModbus.Write16(slaveld, startAddress, value))
                                    {
                                        WriteSignLabel.Text = "写入成功";
                                    }
                                    else
                                    {
                                        WriteSignLabel.Text = "写入失败";
                                    }


                                }
                                catch
                                {
                                    WriteSignLabel.Text = "写入失败";

                                }
                            }


                            break;
                        case "32位整型":
                            {
                                int value;

                                try
                                {
                                    value = Convert.ToInt32(WriteDataTextBox.Text);
                                }
                                catch
                                {
                                    MessageBox.Show("数据错误");
                                    return;
                                }

                                try
                                {

                                    if (MCGSModbus.Write32(slaveld, startAddress, value))
                                    {
                                        WriteSignLabel.Text = "写入成功";
                                    }
                                    else
                                    {
                                        WriteSignLabel.Text = "写入失败";
                                    }


                                }
                                catch
                                {
                                    WriteSignLabel.Text = "写入失败";

                                }
                            }


                            break;

                        case "32位无符号整型":
                            {
                                uint value;

                                try
                                {
                                    value = Convert.ToUInt32(WriteDataTextBox.Text);
                                }
                                catch
                                {
                                    MessageBox.Show("数据错误");
                                    return;
                                }

                                try
                                {

                                    if (MCGSModbus.Write32(slaveld, startAddress, value))
                                    {
                                        WriteSignLabel.Text = "写入成功";
                                    }
                                    else
                                    {
                                        WriteSignLabel.Text = "写入失败";
                                    }


                                }
                                catch
                                {
                                    WriteSignLabel.Text = "写入失败";

                                }
                            }


                            break;
                        case "浮点型":
                            {
                               float  value;

                                try
                                {
                                    value = Convert.ToSingle(WriteDataTextBox.Text);
                                }
                                catch
                                {
                                    MessageBox.Show("数据错误");
                                    return;
                                }

                                try
                                {

                                    if (MCGSModbus.Write32(slaveld, startAddress, value))
                                    {
                                        WriteSignLabel.Text = "写入成功";
                                    }
                                    else
                                    {
                                        WriteSignLabel.Text = "写入失败";
                                    }


                                }
                                catch
                                {
                                    WriteSignLabel.Text = "写入失败";

                                }
                            }


                            break;
                        case "字符":
                            {
                                char  value;

                                try
                                {
                                    value = Convert.ToChar(WriteDataTextBox.Text);
                                }
                                catch
                                {
                                    MessageBox.Show("数据错误");
                                    return;
                                }

                                try
                                {

                                    if (MCGSModbus.Write16(slaveld, startAddress, value))
                                    {
                                        WriteSignLabel.Text = "写入成功";
                                    }
                                    else
                                    {
                                        WriteSignLabel.Text = "写入失败";
                                    }


                                }
                                catch
                                {
                                    WriteSignLabel.Text = "写入失败";

                                }
                            }



                            break;
                        default:

                            break;
                    }


                }
                catch
                {

                    WriteSignLabel.Text = "写入失败";
                }
            }

        }

        //写入多个数据
        private void WriteDatasButton_Click(object sender, EventArgs e)
        {
            mark = true;
            DataParsing(FunctionCodeComboBox2.Text, OffsetTextBox2.Text);
            if (mark)
            {
                try
                {

                    switch (TypeComboBox2.Text)
                    {
                        case "位":
                            {
                                ushort[] value;

                                try
                                {
                                    string[] strArray;
                                
                                        if (WriteDatasTextBox.Text.Contains(","))
                                    {
                                        strArray = WriteDatasTextBox.Text.Split(',');//字符串转数组
                                    }
                                        else
                                    {
                                        strArray = WriteDatasTextBox.Text.Split(',');//字符串转数组
                                    }
                                    value = new ushort[strArray.Length];
                                    for (int i = 0; i < strArray.Length; i++)
                                    {
                                        value[i] = Convert.ToUInt16(strArray[i]);
                                    }
                                }
                                catch
                                {
                                    MessageBox.Show("数据错误");
                                    return;
                                }

                                try
                                {

                                    if (MCGSModbus.WriteBool(slaveld, functionCode, startAddress,(ushort) value.Length, value))
                                    {
                                        WriteSignLabel1.Text = "写入成功";
                                    }
                                    else
                                    {
                                        WriteSignLabel1.Text = "写入失败";
                                    }


                                }
                                catch
                                {
                                    WriteSignLabel1.Text = "写入失败";

                                }
                            }




                            break;

                        case "16位整型":
                            {
                                short[] value;

                                try
                                {
                                    string[] strArray;

                                    if (WriteDatasTextBox.Text.Contains(","))
                                    {
                                        strArray = WriteDatasTextBox.Text.Split(',');//字符串转数组
                                    }
                                    else
                                    {
                                        strArray = WriteDatasTextBox.Text.Split(',');//字符串转数组
                                    }
                                    value = new short[strArray.Length];
                                    for (int i = 0; i < strArray.Length; i++)
                                    {
                                        value[i] = Convert.ToInt16(strArray[i]);
                                    }
                                }
                                catch
                                {
                                    MessageBox.Show("数据错误");
                                    return;
                                }

                                try
                                {

                                    if (MCGSModbus.Write16(slaveld, startAddress, (ushort)value.Length, value))
                                    {
                                        WriteSignLabel1.Text = "写入成功";
                                    }
                                    else
                                    {
                                        WriteSignLabel1.Text = "写入失败";
                                    }


                                }
                                catch
                                {
                                    WriteSignLabel1.Text = "写入失败";

                                }
                            }




                            break;
                        case "16位无符号整型":
                            {
                                ushort[] value;

                                try
                                {
                                    string[] strArray;

                                    if (WriteDatasTextBox.Text.Contains(","))
                                    {
                                        strArray = WriteDatasTextBox.Text.Split(',');//字符串转数组
                                    }
                                    else
                                    {
                                        strArray = WriteDatasTextBox.Text.Split(',');//字符串转数组
                                    }
                                    value = new ushort[strArray.Length];
                                    for (int i = 0; i < strArray.Length; i++)
                                    {
                                        value[i] = Convert.ToUInt16(strArray[i]);
                                    }
                                }
                                catch
                                {
                                    MessageBox.Show("数据错误");
                                    return;
                                }

                                try
                                {

                                    if (MCGSModbus.Write16(slaveld, startAddress, (ushort)value.Length, value))
                                    {
                                        WriteSignLabel1.Text = "写入成功";
                                    }
                                    else
                                    {
                                        WriteSignLabel1.Text = "写入失败";
                                    }


                                }
                                catch
                                {
                                    WriteSignLabel1.Text = "写入失败";

                                }
                            }


                            break;
                        case "32位整型":
                            {
                                int[] value;

                                try
                                {
                                    string[] strArray;

                                    if (WriteDatasTextBox.Text.Contains(","))
                                    {
                                        strArray = WriteDatasTextBox.Text.Split(',');//字符串转数组
                                    }
                                    else
                                    {
                                        strArray = WriteDatasTextBox.Text.Split(',');//字符串转数组
                                    }
                                    value = new int[strArray.Length];
                                    for (int i = 0; i < strArray.Length; i++)
                                    {
                                        value[i] = Convert.ToInt32(strArray[i]);
                                    }
                                }
                                catch
                                {
                                    MessageBox.Show("数据错误");
                                    return;
                                }

                                try
                                {

                                    if (MCGSModbus.Write32(slaveld, startAddress, (ushort)value.Length, value))
                                    {
                                        WriteSignLabel1.Text = "写入成功";
                                    }
                                    else
                                    {
                                        WriteSignLabel1.Text = "写入失败";
                                    }


                                }
                                catch
                                {
                                    WriteSignLabel1.Text = "写入失败";

                                }
                            }


                            break;

                        case "32位无符号整型":
                            {
                                uint[] value;

                                try
                                {
                                    string[] strArray;

                                    if (WriteDatasTextBox.Text.Contains(","))
                                    {
                                        strArray = WriteDatasTextBox.Text.Split(',');//字符串转数组
                                    }
                                    else
                                    {
                                        strArray = WriteDatasTextBox.Text.Split(',');//字符串转数组
                                    }
                                    value = new uint[strArray.Length];
                                    for (int i = 0; i < strArray.Length; i++)
                                    {
                                        value[i] = Convert.ToUInt32(strArray[i]);
                                    }
                                }
                                catch
                                {
                                    MessageBox.Show("数据错误");
                                    return;
                                }

                                try
                                {

                                    if (MCGSModbus.Write32(slaveld, startAddress, (ushort)value.Length, value))
                                    {
                                        WriteSignLabel1.Text = "写入成功";
                                    }
                                    else
                                    {
                                        WriteSignLabel1.Text = "写入失败";
                                    }


                                }
                                catch
                                {
                                    WriteSignLabel1.Text = "写入失败";

                                }
                            }


                            break;
                        case "浮点型":
                            {
                                float[] value;

                                try
                                {
                                    string[] strArray;

                                    if (WriteDatasTextBox.Text.Contains(","))
                                    {
                                        strArray = WriteDatasTextBox.Text.Split(',');//字符串转数组
                                    }
                                    else
                                    {
                                        strArray = WriteDatasTextBox.Text.Split(',');//字符串转数组
                                    }
                                    value = new float[strArray.Length];
                                    for (int i = 0; i < strArray.Length; i++)
                                    {
                                        value[i] = Convert.ToSingle(strArray[i]);
                                    }
                                }
                                catch
                                {
                                    MessageBox.Show("数据错误");
                                    return;
                                }

                                try
                                {

                                    if (MCGSModbus.Write32(slaveld, startAddress, (ushort)value.Length, value))
                                    {
                                        WriteSignLabel1.Text = "写入成功";
                                    }
                                    else
                                    {
                                        WriteSignLabel1.Text = "写入失败";
                                    }


                                }
                                catch
                                {
                                    WriteSignLabel1.Text = "写入失败";

                                }
                            }


                            break;
                        case "字符串":
                            {

                                try
                                {

                                    if (MCGSModbus.WriteString(slaveld, startAddress, WriteDatasTextBox.Text))
                                    {
                                        WriteSignLabel1.Text = "写入成功";
                                    }
                                    else
                                    {
                                        WriteSignLabel1.Text = "写入失败";
                                    }


                                }
                                catch
                                {
                                    WriteSignLabel1.Text = "写入失败";

                                }
                            }



                            break;
                        default:

                            break;
                    }


                }
                catch
                {

                    WriteSignLabel1.Text = "写入失败";
                }
            }


          
        }
  • 6
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值