Modbus-RTU协议C#实现

1、安装依赖包
System.IO.Ports
2、读协议

/// 
        /// Modbus-RTU协议读实例
        /// 
        private static void Read()
        {
            //组装一个请求报文
            // 01 03 00 00 00 0A C5 CD
            byte slave = 0x01;
            //byte function = 0x03;   //读单个寄存器
            byte function = 0x01;   //读单个线圈状态
            int startAddress = 0;
            int length = 10;

            List<byte> bytes = new List<byte>();
            bytes.Add(slave);
            bytes.Add(function);
            bytes.Add(BitConverter.GetBytes(startAddress)[1]);
            bytes.Add(BitConverter.GetBytes(startAddress)[0]);
            bytes.Add(BitConverter.GetBytes(length)[1]);
            bytes.Add(BitConverter.GetBytes(length)[0]);
            //CRC校验
            bytes = CRC16(bytes);
            //组装好了进行串口通信
            SerialPort serialPort = new SerialPort("COM1", 9600, Parity.None, 8, StopBits.One);
            serialPort.Open();
            //向从站发送请求
            serialPort.Write(bytes.ToArray(), 0, bytes.Count);
            Task.Run(async () =>
            {
                await Task.Delay(100);
                byte[] buffer = new byte[serialPort.BytesToRead];
                serialPort.DiscardInBuffer();

                List<byte> bufferList = new List<byte>(buffer);
                bufferList.RemoveAt(0);
                bufferList.RemoveAt(0);
                bufferList.RemoveAt(0);
                bufferList.RemoveAt(bufferList.Count - 1);
                bufferList.RemoveAt(bufferList.Count - 1);
                //读寄存器
                //for(int i = 0; i < bufferList.Count; i++)
                //{
                //    List valueList = new List();
                //    valueList.Add(bufferList[i]);
                //    valueList.Add(bufferList[++i]);
                //    valueList.Reverse();
                //    ushort value=BitConverter.ToUInt16(valueList.ToArray(), 0);
                //    Console.WriteLine(value);
                //}
                //读线圈 09 00
                bufferList.Reverse();
                var values = string.Join("", bufferList.Select(x => Convert.ToString(x, 2).PadLeft(8, '0')).ToList()).ToList();
                values.Reverse();
                for (int i = 0; i < values.Count; i++)
                {
                    Console.WriteLine(Convert.ToBoolean(int.Parse(values[i].ToString())));
                }
            });
        }

3、写协议

/// 
        /// Modbus-RTU协议写实例
        /// 
        private static void Write()
        {
            //组装报文
            byte slave = 0x01;
            //byte function = 0x05;   //写单个线圈状态
            byte function = 0x06;   //写单个寄存器
            int startAddress = 0;
            bool value = false;
            int iv = 123;

            List<byte> bytes = new List<byte>();
            bytes.Add(slave);
            bytes.Add(function);
            bytes.Add(BitConverter.GetBytes(startAddress)[1]);
            bytes.Add(BitConverter.GetBytes(startAddress)[0]);
            //单线圈的写入
            //bytes.Add(value ? (byte)0xFF : (byte)0x00);
            //bytes.Add(0x00);
            //单寄存器写入
            bytes.Add(BitConverter.GetBytes(iv)[1]);
            bytes.Add(BitConverter.GetBytes(iv)[0]);
            //CRC校验
            bytes = CRC16(bytes);
            SerialPort serialPort = new SerialPort("COM1", 9600, Parity.None, 8, StopBits.One);
            serialPort.Open();
            //向从站发送请求
            serialPort.Write(bytes.ToArray(), 0, bytes.Count);
            //接收后如果报文一致,说明发送请求成功
        }

4、CRC16校验

/// 
        /// CRC-16校验
        /// 
        /// 
        /// 
        /// 
        /// 
        /// 
        private static List<byte> CRC16(List<byte> value,ushort poly=0xA001,ushort crcInit=0xFFFF)
        {
            if (value == null || !value.Any())
                throw new ArgumentException("");
            //运算
            ushort crc = crcInit;
            for(int i=0; i<value.Count; i++)
            {
                crc = (ushort)(crc ^ value[i]);
                for(int j=0; j<8; j++)
                {
                    crc=(crc&1)!=0?(ushort)((crc>>1)^poly):(ushort)(crc>>1);
                }
            }
            byte hi = (byte)((crc & 0xFF00) >> 8);
            byte lo=(byte)(crc & 0xFF);
            List<byte> buffer = new List<byte>();
            buffer.AddRange(value);
            buffer.Add(lo);
            buffer.Add(hi);
            return buffer;
        }

你可能感兴趣的:(c#,开发语言)