Modbus RTU通过从站地址获取校验码的代码

主要方法


  • 拆分高低位

image

  • 计算校验码

image

  • 完整通过从站地址获取校验码的代码

using System;
class Program
{
    static void Main()
    {
        Console.Write("请输入从站地址(十六进制): ");
        string slaveAddressInput = Console.ReadLine();
        byte slaveAddress;
        while (!(byte.TryParse(slaveAddressInput, System.Globalization.NumberStyles.HexNumber, null, out slaveAddress)))
        {
            Console.Write("无效的从站地址输入,请输入有效的十六进制值: ");
            slaveAddressInput = Console.ReadLine();
        }

        byte[] command1 = new byte[10];
//01 03 00 00 00 10 44 06
        
        command1[0] = slaveAddress;
        command1[1] = 0x03;
        command1[2] = 0x00;
        command1[3] = 0x00;
        command1[4] = 0x00;
        command1[5] = 0x10;
        byte[] command2 = { command1[0], command1[1], command1[2], command1[3], command1[4], command1[5] };
        byte[] crcBytes = GetCrcBytes(command2);
        command1[6] = crcBytes[0];
        command1[7] = crcBytes[1];
        Console.WriteLine(command1[6].ToString("X2"));
        Console.WriteLine(command1[7].ToString("X2"));
    }
    
    public static ushort CalculateCrc(byte[] data)
    {
        ushort crc = 0xFFFF;

        foreach (byte b in data)
        {
            crc ^= b;

            for (int i = 0; i < 8; i++)
            {
                if ((crc & 0x0001) != 0)
                {
                    crc >>= 1;
                    crc ^= 0xA001; // 这是Modbus RTU协议的生成多项式
                }
                else
                {
                    crc >>= 1;
                }
            }
        }

        return crc;
    }

// 将CRC拆分为低位和高位
    public static byte[] GetCrcBytes(byte[] data)
    {
        ushort crc = CalculateCrc(data);
        byte[] crcBytes = new byte[2];
        crcBytes[0] = (byte)(crc & 0xFF);      // 低位
        crcBytes[1] = (byte)((crc >> 8) & 0xFF); // 高位

        return crcBytes;
    }
}
  • 测试几个结果

image
image

posted @ 2024-02-23 14:42  咸鱼过海  阅读(49)  评论(0编辑  收藏  举报