C# Modbus RTU通讯学习笔记
  6554CEvzIu1g 2023年11月02日 66 0

Modbus RTU 是一种串行通信协议,通常用于工业自动化系统中的设备间通信。它使用二进制编码,支持多个设备在同一通信线路上进行通信。以下是一些关于 Modbus RTU 的信息:

  1. Modbus RTU 是 Modbus 协议的一种变体,它使用 RS-485 串行通信标准。
  2. Modbus RTU 使用 CRC 校验来保证数据传输的完整性和正确性。
  3. Modbus RTU 支持多种数据类型,包括整数、浮点数、布尔值等。
  4. Modbus RTU 通常被用于控制器、传感器、执行器等设备之间的通信。

Modbus比其他通信协议使用的更广泛的主要原因有:

公开发表并且无版权要求 易于部署和维护

对供应商来说,修改移动本地的比特或字节没有很多限制 Modbus允许多个 (大约240个) 设备连接在同一个网络上进行通信,举个例子,一个由测量温度和湿度的装置,并且将结果发送给计算机。

Modbus支持的具体协议有:Modbus TCP、Modbus UDP、Modbus RTU、ModbusRtuOverTcp、Modbus Ascii等。支持Modbus的设备厂高非常多,三菱、西门子等在不同的设备模块上都有支持。

1 modbus 通讯数据格式

地址码

功能码

数据区

校验码

1个字节1

1个字节

N个字节

6位CRC

2 功能码

功能码

描述

说明

MOUBUS地址

01

读输出线圈寄存器

位操作

00001 ~ 09999

02

读离散输入寄存器

位操作

10001 ~ 19999

03

读保持(输出)寄存器

字操作

40001 ~ 49999

04

读输入寄存器

字操作

30001 ~ 39999

05

写单线圈寄存器

位操作

00001 ~ 09999

06

写单线圈保持寄存器

字操作

40001 ~ 49999

07

读取异常状态

获得8个内部线圈的逻辑状态


10

写多路寄存器

字操作


15

写多线圈寄存器

位操作

00001 ~ 09999

16

写多个保持寄存器

字操作

40001 ~ 49999

17


报告从机标识

可使主机判断从机标识的类型及其该从机运行指示灯的状态


3.格式

数据区格式不固定,一般需要查看从机设备的通讯手册
数据区格式示例:

开始编号/寄存器地址

数据个数

数据1

……

数据n

2个字节

2个字节

2个字节

2个字节

2个字节

4.CRC校验算法步骤

第一步:设置CRC变量存储器初始值位0xFFFF;

第二步:把第一个参与校验的数据和CRC变量的低八位进行异或运算,结果仍存到CRC存储器中;

第三步:把CRC右移一位,最高位补0;

第四步:检查刚移出的最低位b0,如果b0=1,则CRC变量和0xA001进行异或运算,结果仍存在CRC变量存储器中,然后执行下一步。如果b0=0,则直接执行下一步;

第五步:重复3、4两步,只到右移8次。这样第一个数据处理就完成了,结果仍存在CRC变量存储器中。

第六步:重复2~5步,处理下一个数据,只到参与校验的数据均处理完毕。 注:最后获得的16位CRC校验值,在传输时,低八位在前,高八位在后;

CRC校验算法C#语言程序

/// <summary>
        /// CRC16_Modbus效验
        /// </summary>
        /// <param name="byteData">要进行计算的字节数组</param>
        /// <returns>计算后的数组</returns>
        public static byte[] ToModbus(byte[] byteData)
        {
            byte[] CRC = new byte[2];

            UInt16 wCrc = 0xFFFF;
            for (int i = 0; i < byteData.Length; i++)
            {
                wCrc ^= Convert.ToUInt16(byteData[i]);
                for (int j = 0; j < 8; j++)
                {
                    if ((wCrc & 0x0001) == 1)
                    {
                        wCrc >>= 1;
                        wCrc ^= 0xA001;//异或多项式
                    }
                    else
                    {
                        wCrc >>= 1;
                    }
                }
            }

            CRC[1] = (byte)((wCrc & 0xFF00) >> 8);//高位在后
            CRC[0] = (byte)(wCrc & 0x00FF);       //低位在前
            return CRC;

        }


【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月08日 0

暂无评论

推荐阅读
6554CEvzIu1g
作者其他文章 更多