Modbus CRC校验

##照抄的这篇帖子,我想在应用层面再表达的简单一点https://www.cnblogs.com/ydong/archive/2007/05/03/735204.html

先贴代码

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

namespace PwProject
{
    public class CrcCheck
    {
        /// <summary>
        /// CRC校验,参数data为byte数组
        /// </summary>
        /// <param name="data">校验数据,字节数组</param>
        /// <returns>字节0是高8位,字节1是低8位</returns>
        public  byte[] CRC16(byte[] data)
        {
            //crc计算赋初始值
            int crc = 0xffff;
            for (int i = 0; i < data.Length; i++)
            {
                crc = crc ^ data[i];
                for (int j = 0; j < 8; j++)
                {
                    int temp;
                    temp = crc & 1;
                    crc = crc >> 1;
                    crc = crc & 0x7fff;
                    if (temp == 1)
                    {
                        crc = crc ^ 0xa001;
                    }
                    crc = crc & 0xffff;
                }
            }
            //CRC寄存器的高低位进行互换
            byte[] crc16 = new byte[2];
            //CRC寄存器的高8位变成低8位,
            crc16[1] = (byte)((crc >> 8) & 0xff);
            //CRC寄存器的低8位变成高8位
            crc16[0] = (byte)(crc & 0xff);
            return crc16;
        }

        /// <summary>
        /// CRC校验,参数为空格或逗号间隔的字符串
        /// </summary>
        /// <param name="data">校验数据,逗号或空格间隔的16进制字符串(带有0x或0X也可以),逗号与空格不能混用</param>
        /// <returns>字节0是高8位,字节1是低8位</returns>
        public  byte[] CRC16(string data)
        {
            //分隔符是空格还是逗号进行分类,并去除输入字符串中的多余空格
            IEnumerable<string> datac = data.Contains(",") ? data.Replace(" ", "").Replace("0x", "").Replace("0X", "").Trim().Split(',') : data.Replace("0x", "").Replace("0X", "").Split(' ').ToList().Where(u => u != "");
            List<byte> bytedata = new List<byte>();
            foreach (string str in datac)
            {
                bytedata.Add(byte.Parse(str, System.Globalization.NumberStyles.AllowHexSpecifier));
            }
            byte[] crcbuf = bytedata.ToArray();
            //crc计算赋初始值
            int crc = 0xffff;
            for (int i = 0; i < crcbuf.Length; i++)
            {
                crc = crc ^ crcbuf[i];
                for (int j = 0; j < 8; j++)
                {
                    int temp;
                    temp = crc & 1;
                    crc = crc >> 1;
                    crc = crc & 0x7fff;
                    if (temp == 1)
                    {
                        crc = crc ^ 0xa001;
                    }
                    crc = crc & 0xffff;
                }
            }
            //CRC寄存器的高低位进行互换
            byte[] crc16 = new byte[2];
            //CRC寄存器的高8位变成低8位
            crc16[1] = (byte)((crc >> 8) & 0xff);
            //CRC寄存器的低8位变成高8位
            crc16[0] = (byte)(crc & 0xff);

            return crc16;
        }

    }
}

应用层,下图是我用modbus poll生成的应答信号,poll已经帮我们做好了校验,但是最终是要集成到代码里的,还是得自己能写才行,橙色圈是数据帧,绿色笔就是我们要的结果。 在这里插入图片描述

可以看到我就是把橙色笔圈出来的东西抠出来,然后给到函数处理,接下来我们看一下返回值。下面两张图里可以看到返回值和modbus poll生成的是一致的。

CrcCheck cc = new CrcCheck();
byte[] result=cc.CRC16(new byte[]{0x01,0x03,0x00,0x6a,0x00,0x02});

在这里插入图片描述

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_42485732/article/details/125642669