Modbus-RTU协议讲解与实战

1、背景

工作需要,需要使用Modbus-RTU实现RS485通信,于是简单学习并实践了一下。

2、参考资料

一文看懂Modbus协议

3、协议说明

3.1、协议类型

当前设备采用Modbus-RTU协议,采用CRC-16_Modbus校验算法,数据链路层使用用标准串口协议,物理层采用RS485进行数据传输。

3.2、帧结构

帧结构 说明
地址码(1) 指定待通信的设备地址,可以是广播地址、单设备地址或多设备地址。地址码占1字节,有效值范围是1~247。
功能码 (1) 指令类型,详细说明程序执行的操作是读取、写入还是查询串口通信协议。功能码占1字节,有效值范围是1~255
起始地址(2) 寄存器地址,2个字节
数据(N) 根据执行的命令指令来封装数据内容,数据长度为多字节
CRC校验码(2) 数据传输前需要计算校验和,检验数据是否传输正确。CRC校验占2字节

3.3、功能码

功能码 说明
01H 读取输出线圈
02H 读取输入线圈
03H 读取保持寄存器
04H 读取输入寄存器
05H 写入单线圈
06H 写入单寄存器
0FH 写入多线圈
10H 写入多寄存器

4、协议主、从机数据交互

4.1、数据帧格式

4.1.1、读数据 读单个或多个寄存器03H

1)主机发送

从机地址 功能码 寄存器起始地址 寄存器个数 CRC16校验
1Byte 1Byte 2Byte,高字节在前 2Byte,高字节在前 2Byte,低字节在前

2)从机接收

从机地址 功能码 数据长度(字节数) 寄存器数据 CRC16校验
1Byte 1Byte 1Byte N,高字节在前 2Byte,低字节在前

4.1.2、写数据 写单个寄存器06H

1)主机发送

从机地址 功能码 寄存器起始地址 寄存器数据 CRC16校验
1Byte 1Byte 2Byte,高字节在前 N,高字节在前 2Byte,低字节在前

2)从机接收

从机地址 功能码 寄存器起始地址 寄存器数据 CRC16校验
1Byte 1Byte 2Byte,高字节在前 N,高字节在前 2Byte,低字节在前

4.1.3、写数据 写多个寄存器10H

1)主机发送

从机地址 功能码 寄存器起始地址 寄存器数量 寄存器数据总字节数(2*寄存器数量) 数据 CRC16校验
1Byte 1Byte 2Byte,高字节在前 2Byte,高字节在前 1Byte N,高字节在前 2Byte,低字节在前

2)从机接收

从机地址 功能码 寄存器起始地址 寄存器数量 CRC16校验
1Byte 1Byte 2Byte,高字节在前 2Byte,高字节在前 2Byte,低字节在前

5、协议示例

5.1、寄存器地址划分

在这里插入图片描述

5.2 、查询03H

5.2.1 、查询两个寄存器

单个寄存器对应寄存器数量设为01H,可以自行实现

  • 主机发送帧
    在这里插入图片描述
  • 从机回复帧
    在这里插入图片描述

5.2.2 查询N个寄存器

  • 主机发送帧
    在这里插入图片描述
  • 从机回复帧
    在这里插入图片描述

5.3、设置

5.3.1、主机设置单个寄存器的值

就是写数据帧

  • 主机发送帧
    在这里插入图片描述
  • 从机回复帧
    在这里插入图片描述

5.3.2、主机设置两个寄存器的值

  • 主机发送数据帧
    在这里插入图片描述
  • 从机回复数据帧
    在这里插入图片描述

5.3.3 、主机设置N个寄存器的值

  • 主机发送数据帧
    在这里插入图片描述

  • 从机回复数据帧
    在这里插入图片描述

6、计算校验值

6.1、crc16在线计算校验值

CRC(循环冗余校验)在线计算

RC校验(循环冗余校验)小知识 CRC即循环冗余校验码(Cyclic Redundancy
Check):是数据通信领域中最常用的一种查错校验码,其特征是信息字段和校验字段的长度可以任意选定。循环冗余检查(CRC)是一种数据传输检错功能,对数据进行多项式计算,并将得到的结果附在帧的后面,接收设备也执行类似的算法,以保证数据传输的正确性和完整性。

CRC算法参数模型解释: NAME:参数模型名称。 WIDTH:宽度,即CRC比特数。
POLY:生成项的简写,以16进制表示。例如:CRC-32即是0x04C11DB7,忽略了最高位的"1",即完整的生成项是0x104C11DB7。
INIT:这是算法开始时寄存器(crc)的初始化预置值,十六进制表示。 REFIN:待测数据的每个字节是否按位反转,True或False。
REFOUT:在计算后之后,异或输出之前,整个数据是否按位反转,True或False。
XOROUT:计算结果与此参数异或后得到最终的CRC值。

其他相关工具:LRC校验BCC校验

提示:复制数据时请注意字符串首尾的一些不可见字符!

在这里插入图片描述

注意:要注意校验值高字节低字节的顺序,必要时需要转换位置
在这里插入图片描述

其他参考资料:
主机实现:
Modbus主机实现
从机实现:
Modbus从机实现
https://blog.csdn.net/weixin_31301271/article/details/120334602

6.2、代码实现

6.2.1、crc16校验

注意:注意高低字节位置

#include <stdio.h>


/* CRC余式表 */
const unsigned int crc_table[256] = {
   
    0x0000, 0xc0c1, 0xc181, 0x0140, 0xc301, 0x03c0, 0x0280, 0xc241,
    0xc601, 0x06c0,
  • 19
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

月如琉璃

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值