合肥网站建设设计外包,汕头建站平台,旅游网站建设电子商务的困惑,设计师关注的十大网站1、背景
工作需要,需要使用Modbus-RTU实现RS485通信,于是简单学习并实践了一下。
2、参考资料
一文看懂Modbus协议
3、协议说明
3.1、协议类型
当前设备采用Modbus-RTU协议,采用CRC-16_Modbus校验算法,数据链路层使用用标准串口协议,物理层采用RS485进行数据传输。 …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校验1Byte1Byte2Byte,高字节在前2Byte,高字节在前2Byte,低字节在前2)从机接收
从机地址功能码数据长度(字节数)寄存器数据CRC16校验1Byte1Byte1ByteN,高字节在前2Byte,低字节在前4.1.2、写数据 写单个寄存器06H
1)主机发送
从机地址功能码寄存器起始地址寄存器数据CRC16校验1Byte1Byte2Byte,高字节在前N,高字节在前2Byte,低字节在前2)从机接收
从机地址功能码寄存器起始地址寄存器数据CRC16校验1Byte1Byte2Byte,高字节在前N,高字节在前2Byte,低字节在前4.1.3、写数据 写多个寄存器10H
1)主机发送
从机地址功能码寄存器起始地址寄存器数量寄存器数据总字节数(2*寄存器数量)数据CRC16校验1Byte1Byte2Byte,高字节在前2Byte,高字节在前1ByteN,高字节在前2Byte,低字节在前2)从机接收
从机地址功能码寄存器起始地址寄存器数量CRC16校验1Byte1Byte2Byte,高字节在前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,