Modbus通讯协议学习 - 认识篇

错误检测域

LRC(纵向冗长检测)

ASCII消息帧

位顺序(ASCII)

RTU消息帧

8位二进制,十六进制数0…9,A…F

消息中的每个8位域都是一个两个十六进制字符组成

每个字节的位

1个起始位

8个数据位,最小的有效位先发送

1个奇偶校验位,无校验则无

1个停止位(有校验时),2个Bit(无校验时)

错误检测域

CRC(循环冗长检测)

RTU消息帧

位顺序(RTU)

CRC校验 (http://baike.baidu.com/view/1664507.htm)

复制代码

public static string CRCCheck(string val)

    {
        val \= val.TrimEnd(' ');
        string\[\] spva = val.Split(' ');
        byte\[\] bufData = new byte\[spva.Length + 2\];
        bufData \= ToBytesCRC(val);
        ushort CRC = 0xffff;
        ushort POLYNOMIAL = 0xa001;
        for (int i = 0; i < bufData.Length - 2; i++)
        {
            CRC ^= bufData\[i\];
            for (int j = 0; j < 8; j++)
            {
                if ((CRC & 0x0001) != 0)
                {
                    CRC \>>= 1;
                    CRC ^= POLYNOMIAL;
                }
                else
                {
                    CRC \>>= 1;
                }
            }
        }
        return Maticsoft.DBUtility.HLConvert.ToHex(System.BitConverter.GetBytes(CRC));
    }
    /// <summary>
    /// 例如把如下字符串转换成字节数组
    /// AA AA AA AA 0A 00 68 00 06 03 04 54 21 28 22 E5 F3 16 BB BB BB BB   转换为字节数组
    /// </summary>
    /// <param name="hex">十六进制字符串</param>
    /// <returns></returns>
    public static byte\[\] ToBytesCRC(string hex)
    {
        string\[\] temp = hex.Split(' ');
        byte\[\] b = new byte\[temp.Length + 2\];
        for (int i = 0; i < temp.Length; i++)
        {
            b\[i\] \= Convert.ToByte(temp\[i\], 16);
        }
        return b;
    }
    /// <summary>
    /// 将字节数据转换为十六进制字符串,中间用 “ ”分割 如:AA AA AA AA 0A 00 68 00 06 03 04 54 21 28 22 E5 F3 16 BB BB BB BB
    /// </summary>
    /// <param name="vars">要转换的字节数组</param>
    /// <returns></returns>
    public static String ToHex(byte\[\] vars)
    {
        return BitConverter.ToString(vars).Replace('\-', ' ').Trim();
    }

复制代码

CS校验(累加和)

复制代码

public static string CSCheck(string str)

    {
        if (str.Length == 0) return "";
        else str = str.Trim();
        byte\[\] sss = ToBytes(str);
        int n = 0;
        for (int i = 0; i < sss.Length; i++)
        {
            n += sss\[i\];
        }
        return ToHex(n);
    }
    /// <summary>
    /// AB CD 12 3B     转换为字节数组
    /// </summary>
    /// <param name="hex">十六进制字符串</param>
    /// <returns></returns>
    public static byte\[\] ToBytes(string hex)
    {
        string\[\] temp = hex.Split(' ');
        byte\[\] b = new byte\[temp.Length\];
        for (int i = 0; i < temp.Length; i++)
        {
            if (temp\[i\].Length > 0)
                b\[i\] \= Convert.ToByte(temp\[i\], 16);
        }
        return b;
    }
    /// <summary>
    /// 转换为符合本程序的十六进制格式
    /// </summary>
    /// <param name="var">1 2 3 等。</param>
    /// <returns>返回十六进制字符串,如果是1-9的话,前面带零</returns>
    /// <example>例如: 5  ="05"  12 ="0C" 无论何时,都是两位数。  </example>
    public static string ToHex(int var)
    {
        int cs = var;
        string tmp = "";
        if (cs == 0) { tmp = "00"; }
        while (cs > 0)
        {
            int ys;
            cs \= Math.DivRem(cs, 256, out ys);
            tmp \= tmp.Insert(0, string.Format(" {0}", Right("00" + Convert.ToString(ys, 16), 2).ToUpper()));
        }
        return tmp.Trim();
    }
    public static string Right(string str, int Length)
    {
        if ((Length <= 0) || (str == null))
        {
            return "";
        }
        int length = str.Length;
        if (Length >= length)
        {
            return str;
        }
        return str.Substring(length - Length, Length);
    }

复制代码

LRC校验(LRC错误校验用于ASCII模式)

复制代码

///

    /// 取模FF(255)
    /// 取反+1
    /// </summary>
    /// <param name="writeUncheck"></param>
    /// <returns></returns>
    public static string LRCheck(string writeUncheck)
    {
        char\[\] hexArray = new char\[writeUncheck.Length\];
        hexArray \= writeUncheck.ToCharArray();
        int decNum = 0, decNumMSB = 0, decNumLSB = 0;
        int decByte, decByteTotal = 0;
        bool msb = true;
        for (int t = 0; t <= hexArray.GetUpperBound(0); t++)
        {
            if ((hexArray\[t\] >= 48) && (hexArray\[t\] <= 57))
                decNum \= (hexArray\[t\] - 48);
            else if ((hexArray\[t\] >= 65) & (hexArray\[t\] <= 70))
                decNum \= 10 + (hexArray\[t\] - 65);
            if (msb)
            {
                decNumMSB \= decNum \* 16;
                msb \= false;
            }
            else
            {
                decNumLSB \= decNum;
                msb \= true;
            }
            if (msb)
            {
                decByte \= decNumMSB + decNumLSB;
                decByteTotal += decByte;
            }
        }
        decByteTotal \= (255 - decByteTotal) + 1;
        decByteTotal \= decByteTotal & 255;
        int a, b = 0;
        string hexByte = "", hexTotal = "";
        double i;
        for (i = 0; decByteTotal > 0; i++)
        {
            b \= Convert.ToInt32(System.Math.Pow(16.0, i));
            a \= decByteTotal % 16;
            decByteTotal /= 16;
            if (a <= 9)
                hexByte \= a.ToString();
            else
            {
                switch (a)
                {
                    case 10:
                        hexByte \= "A";
                        break;

最后

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,不论你是刚入门Java开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!

如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。**

[外链图片转存中…(img-gGUfdHES-1715829119100)]

[外链图片转存中…(img-DsSzxolv-1715829119101)]

[外链图片转存中…(img-O7Y6xix8-1715829119101)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,不论你是刚入门Java开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!

如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值