Rola学习|modbus协议学习笔记
学习并理解modbus协议笔记
- 一.简介
- 1.介绍
- 2.协议描述
- 二.关键知识点
- 1.常用功能码寄存器的理解
- 2.发送数据帧单元的理解
- 3.对modbus协议检错(异常相应)的理解
- 对于这个协议标准,还得完全吃透,先了解总的构架,在对其各个突破。加油!
一.简介 1.介绍
- Modbus是一种串行通信协议,是Modicon公司(现在的施耐德电气 Schneider Electric)于1979年为使用可编程逻辑控制器(PLC)通信而发表。Modbus已经成为工业领域通信协议的业界标准(De facto),并且现在是工业电子设备之间常用的连接方式。
- 有两种串行传输模式被定义: RTU(Remote Terminal Unit) 模式 和 ASCII 模式。
它定义了报文域的位内容在线路上串行的传送。它确定了信息如何打包为报文和解码。
Modbus 串行链路 上所有设备的传输式 模式 ( ( 和串行口参数) ) 必须 相同。
尽管在特定的领域 ASCII 模式是要求的,但达到 Modbus 设备之间的互操作性只有每个设备都有
相同的模式: 所有设备 必须现 必须实现 RTU 模式。 ASCII 传输模式是选项。
设备应该由用户设成期望的模式, RTU 或 ASCII。 默认设置必须为 RTU 模式。
- 对于串行连接两个传输模式,它们在数值数据表示不同和协议细节上略有不同。Modbus RTU是一种紧凑的,采用二进制表示数据的方式(由于我们进行通信的一般数据包为2进制形式,所以我们一般都采用RTU模式),Modbus ASCII是一种人类可读的,冗长的表示方式。这两个变种都使用串行通信(serial communication)方式。RTU(Remote Terminal Unit)格式后续的命令/数据带有循环冗余校验(CRC)的校验和,而ASCII格式采用纵向冗余校验的校验和。被配置为RTU变种的节点不会和设置为ASCII变种的节点通信,反之亦然。
- MODBUS 是一个请求/应答协议,并且提供功能码规定的服务MODBUS 功能码是 MODBUS
请求/应答 PDU 的元素。
的 MODBUS 协议映射能够在应用数据单元(ADU)上引入一些附加域。
文章图片
通过这个数据帧并对应相应功能实现数据包的传输。
二.关键知识点 1.常用功能码寄存器的理解 modbus协议完整支持很多功能码,但是实际在应用的不多。具体如下:
0x01 :读线圈寄存器(注意:这些寄存器属于软件编写的给一段空间来定义相关参数)
0x02 :读离散输入寄存器
0x03 :读保持寄存器
0x04 :读输入寄存器
0x05 :写单个线圈寄存器
0x06 :写单个保持寄存器
0x0f :写多个线圈寄存器
0x10 :写多个保持寄存器
文章图片
分析:
- 对线圈寄存器的读写实质上可以通过led来理解,对定义的每个bit进行读写,通过远程通信发送的数据帧,根据modbus协议定义的线圈寄存器,与调用led转换的代码,与之间接实现控制led的IO口,我的理解就是比如在我的有一篇博客中讲sx1278芯片寄存器的功能与读写,而这里就是用代码来实现寄存器的位数与其他功能模块调用挂钩,以实现控制的原理。
- 而离散输入寄存器按照线圈寄存器理解一样的,只是离散输入寄存器规定只读模式,比如只能读取LED的IO口状态 。
- 对于保持寄存器则是对2byte数据进行读写,最基本的功能就是自定义数据类型,然后主机模块的测量温度的传感器的数据(16进制2byte)发送给从机接收,再由从机直接把数据通过串口显示出来。
- 输入寄存器与保持寄存器类似,但也是只支持读而不能写。
从机地址 | 功能码 | 寄存器首地址 | 寄存器数量 | crc 效验码 |
---|---|---|---|---|
01 | 01 | 1001 | 0003 | 290B |
- 从机地址,0x01这个我们在代码中设置即可。
- 功能码,0x01读线圈寄存器。
- 起始地址,0x1001也是在协议代码中定义。
- 数量,0x0003,3个led的状态。
- CRC效验码,根据一种crc算法计算,在确定了前面6个字节后自动加效验码(协议代码中体现)。
3.对modbus协议检错(异常相应)的理解 当客户机设备向服务器设备发送请求时,客户机希望一个正常响应。从主站询问中出现下列四种可能事件之一:
- 如果服务器设备接收到无通信错误的请求,并且可以正常地处理询问,那么服务器设备将
返回一个正常响应。 - 如果由于通信错误,服务器没有接收到请求,那么不能返回响应。客户机程序将最终处理
请求的超时状态。 - 如果服务器接收到请求,但是检测到一个通信错误(奇偶校验、LRC、CRC、…),那么不
能返回响应。客户机程序将最终处理请求的超时状态。 - 如果服务器接收到无通信错误的请求,但不能处理这个请求(例如,如果请求读一个不存
在的输出或寄存器),服务器将返回一个异常响应,通知用户错误的本质特性。
- 功能码域 :在正常响应中,服务器利用响应功能码域来应答最初请求的功能码。所有功能码的
最高有效位(MSB)都为 0(它们的值都低于十六进制 80)。在异常响应中,服务器设置功能码的MSB 为 1。这使得异常响应中的功能码值比正常响应中的功能码值高十六进制 80。
通过设置功能码的 MSB,客户机的应用程序能够识别异常响应,并且能够检测异常码的数据域。 - 数据域 :在正常响应中,服务器可以返回数据域中数据或统计表(请求中要求的任何报文)。在
异常响应中,服务器返回数据域中的异常码。这就定义了产生异常的服务器状态。
/* RTU 应答代码 */#define RSP_OK0/* 成功 */
#define RSP_ERR_CMD0x01 /* 不支持的功能码 */
#define RSP_ERR_REG_ADDR 0x02 /* 寄存器地址错误 */
#define RSP_ERR_VALUE0x03 /* 数据值域错误 */
#define RSP_ERR_WRITE0x04 /* 写入失败 */
【Rola学习|modbus协议学习笔记】在接收时设置函数,分别判断接收缓冲区的每个字节位,判断跟我们设置的标准有无出入即可以判断是哪部分错误,比如如果我们判断功能域不为我们所规定的的那常见的几个,我们就判断功能域错误,也就是从机返回的数据帧中数据域代码为RSP_ERR_CMD 0x01/* 不支持的功能码 */。其他的类似判断。
对于这个协议标准,还得完全吃透,先了解总的构架,在对其各个突破。加油!
推荐阅读
- 由浅入深理解AOP
- 继续努力,自主学习家庭Day135(20181015)
- python学习之|python学习之 实现QQ自动发送消息
- 一起来学习C语言的字符串转换函数
- 定制一套英文学习方案
- 漫画初学者如何学习漫画背景的透视画法(这篇教程请收藏好了!)
- 《深度倾听》第5天──「RIA学习力」便签输出第16期
- 如何更好的去学习
- 【韩语学习】(韩语随堂笔记整理)
- 焦点学习田源分享第267天《来访》