C# MODBUS RTU 通信 第二章-一、 不使用库

时间:2024-11-03 19:53:15

写单个寄存器

        public void SendModbusData(SerialPort serialPort, byte deviceAddress, ushort registerAddress, ushort registerValue)
        {
            byte[] modbusFrame = new byte[8];
            modbusFrame[0] = deviceAddress; // 设备地址
            modbusFrame[1] = 0x06; // 功能码 (写单个寄存器)
            modbusFrame[2] = (byte)(registerAddress >> 8); // 寄存器地址高字节
            modbusFrame[3] = (byte)(registerAddress & 0xFF); // 寄存器地址低字节
            modbusFrame[4] = (byte)(registerValue >> 8); // 寄存器值高字节
            modbusFrame[5] = (byte)(registerValue & 0xFF); // 寄存器值低字节
                                                           // 计算CRC
            ushort crc = CalculateCRC(modbusFrame, 6);
            modbusFrame[6] = (byte)(crc & 0xFF); // CRC低字节
            modbusFrame[7] = (byte)(crc >> 8); // CRC高字节
                                               // 发送数据
            if (serialPort.IsOpen)
            {
                serialPort.Write(modbusFrame, 0, modbusFrame.Length);
            }
            else
            {
                throw new InvalidOperationException("串口未打开");
            }
        }
     

数据校验

   private ushort CalculateCRC(byte[] data, int length)
        {
            ushort crc = 0xFFFF;
            for (int pos = 0; pos < length; pos++)
            {
                crc ^= (ushort)data[pos];
                for (int i = 8; i != 0; i--)
                {
                    if ((crc & 0x0001) != 0)
                    {
                        crc >>= 1;
                        crc ^= 0xA001;
                    }
                    else
                    {
                        crc >>= 1;
                    }
                }
            }
            return crc;
        }

读取单个寄存器

        public void SendModbusQuery(SerialPort serialPort, byte deviceAddress, ushort registerAddress)
        {
            byte[] modbusFrame = new byte[8];
            modbusFrame[0] = deviceAddress; // 设备地址
            modbusFrame[1] = 0x03; // 功能码 (读取单个寄存器)
            modbusFrame[2] = (byte)(registerAddress >> 8); // 寄存器地址高字节
            modbusFrame[3] = (byte)(registerAddress & 0xFF); // 寄存器地址低字节
            modbusFrame[4] = 0x00; // 读取一个寄存器,寄存器数目高字节
            modbusFrame[5] = 0x01; // 读取一个寄存器,寄存器数目低字节
                                   // 计算CRC
            ushort crc = CalculateCRC(modbusFrame, 6);
            modbusFrame[6] = (byte)(crc & 0xFF); // CRC低字节
            modbusFrame[7] = (byte)(crc >> 8); // CRC高字节
                                               // 发送数据
            if (serialPort.IsOpen)
            {
                serialPort.Write(modbusFrame, 0, modbusFrame.Length);
            }
            else
            {
                throw new InvalidOperationException("串口未打开");
            }
        }