Modbus协议简易入门教程
关注+星标公众号,不错过精彩内容
转自 | 小麦大叔
之前有不少读者在问关于Modbus协议相关的问题,今天给大家分享一篇由小麦大叔整理的Modbus协议教程。
背景
介绍modbus rtu
之前,我们可以了解到,Modbus
是施耐德电气公司,于1979年发明的,是全球第一个真正用于工业现场的总线协议。四十多年过去了,现在仍然被广泛使用在各个工业控制领域。除了这个协议很稳定的原因之外:
免费;
方便部署和维护;
对供应商来说,修改移动本地的比特或字节没有很多限制;
modbus
是OSI
模型第七层上的应用层报文传输协议,OSI
定义了开放系统的层次结构、层次之间的相互关系以及各层所包括的可能的任务,作为一个框架来协调和组织各层所提供的服务。
OSI
参考模型并没有提供一个可以实现的方法,而是描述了一些概念,用来协调进程间通信标准的制定。即OSI
参考模型并不是一个标准,而是一个在制定标准时所使用的概念性框架。
modbus
在OSI
模型中,可以描述为下图;
EIA485
/TIA485
就是RS485
,随着技术不断发展,485标准目前是电信行业协会(TIA)维护,所以名称为TIA-485,当然工程师及应用指南仍继续用RS-485来称呼也是没问题的;
下面我们来介绍一些串行链路协议。
Modbus 串行链路协议
Modbus
串行链路协议是一个主从模式(主机和从机),半双工的数据传输协议,485标准通常需要两条线,在某一个确定时刻,有一个主机和从机进行通讯。
主从模式:通常总线上有一个主机和多个从机,每个从机有唯一的ID,主机通过ID进行寻址从机,然后进行数据传输;
半双工传输:相对应半双工的是全双工,全双工运行发送数据和接收数据同时发生,所以半双工就不难理解了,同一时刻只能进行发送数据,或者只能接收数据;
整体的结构图如下所示;
这里我们还要明确几点:
从机无法主动向从机发送数据,只有在主机发送数据给从机(发送请求),然后从机接收到主机发送的数据之后,再回传数据给主机;具体如下所示;
正如前面所提到的,modbus
是半双工传输的,即主机发送数据的时候,是不能接收数据的,所以这里总共分为两步来进行。
主机发送数据的方式有两种,一个是 1对1,一个是1对多,也就是我们常说的广播形式,所有从机都可以收到主机发送的数据;
1对1 只需要发送数据给特定地址的从机即可,广播只需要把发送地址设置为0即可,所以广播地址为0;
这里我们已经大致了解了主机和从机之间的数据传输的情况,下面我们就再来介绍一下数据传输的具体格式;
传输模式
先来说说Modbus有两种传输模式,RTU传输模式和ASCII传输模式;
RTU传输:
Remote Terminal Unit
模式在Modbus中消息由十六进制组成,数据密度高,吞吐率高;ASCII传输:消息由ASCII 字符发送效率不及RTU模式,无法使用RTU模式的定时管理时,使用ASCII模式;
比如:
0x12
会被整合成两个字符发送:0x31
和0x32
发送,因为
0x31
等于字符1;0x32
等于字符2
下面我们会主要介绍modbus RTU
。
帧格式
在讲帧格式之前,首先我们想象一下,人与人之间的对话,最基本单元是汉字,然后相互交流就用汉字组成的句子,比如下面的对话;
老板问:中午吃什么?
小樟说:吃饭吧!
所以机器之间的通信也是类似的,我们可以把字节当作最基本的数据单元,然后由字节组成句子,也就是通信帧;
但是现在情况出现了变化,对话的人里,除了小樟,还有一个小红,这时候,为了明确和谁说话,就需要在对话前面加上名字:
老板:小樟,中午吃面吗?
小樟:老板,吃饭去吧。
小红,没有叫他,语言柚子;
所以我们继续回到modbus
的数据帧格式,这里的协议定义了一个基础通信层的简单协议数据单元(PDU
),具体如下图所示;
所以这里基本分为四个部分,地址域,功能码,数据,差错校验(CRC/LRC),统称为ADU (Application Data Unit
),基本上进行传输的数据都要满足这个格式,作为一个完整的帧,对照前面老板的对话内容,我们这里可以简单的理解一下:
地址域:可以理解成 具体和谁说话;
功能码:可以理解成 具体动作,比如 去做,来拿,去吃 等等;
数据:可以理解成 具体内容,比如 面,饭 等等,也可以是其他,这里配合上下文,所以是吃的东西;
差错校验:可以理解成,说出来的话必须可以让人理解,不然别人听不懂啊;实际上在协议中通常使用CRC或LRC保证传输的数据没有错误;
下面我们再深入分析一下;
PDU
Modbus PDU(protocol data unit
)格式被定义为一个功能代码,后面跟着一组关联的数据。
该数据的大小和内容由功能代码定义,整个PDU(功能代码和数据)的大小不能超过253个字节。
每个功能代码都有一个特定的行为,从设备可以根据所需的应用程序行为灵活地实现这些行为。
PDU规范定义了数据访问和操作的核心概念;但是,从设备可能会以规范中未明确定义的方式处理数据。
地址域
地址域占用一个字节,所以一般来说寻址范围是0~255
,一般在系统中用1~147
,其他地址暂时保留,另外,同一个总线上的从机,每个地址必须唯一。
其中0
是广播地址;
下面是Freemodbus的一个从机初始化代码,0x02
就是这个从机的地址,
eMBInit(MB_RTU, 0x02, 3, 115200, MB_PAR_NONE);
功能码
功能码占一个字节,所以范围是 0~255
,协议中规定了功能码分为三类:公共功能码,用户自定义功能码,保留功能码。整体如下所示;
公共功能码必须保证它的唯一性,这是由Modbus组织已经规定好,并且具有一致性测试的功能码,所以在一定程度上,它保证了协议的可复用性。
由上表可知,公共功能码分为四种,分别是:
离散量输入:只读类型,单位:
bit
;线圈:读写类型,单位:
bit
;输入寄存器:只读类型,单位:字节;
保持寄存器:读写类型,单位:字节;
下面是移植Freemodbus协议,从机上需要对这四个公共功能码处理的回调函数:
//输入寄存器量
eMBErrorCode eMBRegInputCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNRegs )
{eMBErrorCode eStatus = MB_ENOERR;return eStatus;
}
//保持寄存器量
eMBErrorCode
eMBRegHoldingCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNRegs,eMBRegisterMode eMode )
{eMBErrorCode eStatus = MB_ENOERR;return eStatus;
}//线圈数量
eMBErrorCode
eMBRegCoilsCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNCoils,eMBRegisterMode eMode )
{eMBErrorCode eStatus = MB_ENOERR;return eStatus;
}//离散输入数量
eMBErrorCode
eMBRegDiscreteCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNDiscrete )
{eMBErrorCode eStatus = MB_ENOERR;return eStatus;
}
底层如何传输
我们先看一下最底层modbus数据是如何发送的,没错,看到RS485和232,那我们自然想到了串口。
所以最根本的数据格式可以参考一下串口数据的定义,也就是我们说的起始位,数据位,校验位,数据位;具体如下所示;
所以这里我们可以规定一下:
起始位+数据位+校验位(可选)+ 停止位 等于一个字符;因此这里可以通过串口的波特率去计算出单个字符所需要的时间。
然后我们再看一下,modbus帧是如何发送的?
在RTU
模式中,帧之间的间隔至少为3.5个字符的空闲时间间隔,以便于表示帧的开始和帧的结束,所以如果想自己整一个modbus rtu
就需要一个定时器去结算空闲时间的长度。
整个数据必须以连续的字符流进行发送,如果两个字符之间的长度等于1.5个字符时间,则认为帧消息不完整,则认为设备不该接收该消息,具体如下所示;
这里需要注意的是RTU需要定时器中断的参与,所以,1.5字符时间和3.5字符时间的检测,在串口通讯速率很高的时候,需要高频率得进入中断,这就会增加系统开销。
所以通常在波特率低于19200
的时候,可以严格遵守1.5和3.5字符时间的规定。
如果波特率大于19200
的时候,需要满足两个固定时间即可:
1.5字符时间:750 us;
3.5字符时间:1.75ms;
总结
本文简单介绍了modbus rtu
协议,包括串行链路通信,帧格式以及硬件链路层的消息格式,能力有限,本文难免存在错误和纰漏,请不吝赐教。篇幅有限本文先到这里,下一篇介绍一下如何移植Freemodbus协议以及调试协议的过程。
如何本文帮到了您,请帮忙点赞鼓励一下。
------------ END ------------
关注公众号回复“加群”按规则加入技术交流群,回复“1024”查看更多内容。
点击“阅读原文”查看更多分享。
Modbus协议简易入门教程相关推荐
- layui个人中心html,Layui的简易入门教程
layui是一款采用自身模块规范编写的前端UI框架,非常适合界面的快速开发.本篇文章给大家分享一下Layui的简易入门教程,介绍一下layui如何在你的项目中使用. 获得 layui 后,将其完整地部 ...
- Markdown 简易入门教程
自己整理的 Markdown 简介.编辑器推荐.语法.特征等,是 Markdown 的简易入门教程 目录 概述 简介 官方文档 Markdown编辑器 初级语法 标题 粗体和斜体 段落和换行 分隔线 ...
- FL studio 20简易入门教程 -- 第四篇 -- 钢琴卷帘窗口与单轨乐器编辑界面
钢琴卷帘窗口与单轨乐器编辑界面 本文经验主要来自于B站爱编曲网官方正版快速入门教程,链接如下: 爱编曲网官方正版快速入门教程 文章目录 钢琴卷帘窗口与单轨乐器编辑界面 前言 单轨乐器编辑界面 上方菜单 ...
- FL studio 20简易入门教程 -- 第九篇 -- 完整编曲流程
技巧合集 本文经验主要来自于B站爱编曲网官方正版快速入门教程,链接如下: 爱编曲网官方正版快速入门教程 文章目录 技巧合集 前言 完整编曲流程 1.设置速度 2.内容录制 3.钢琴卷帘窗口编辑 4.设 ...
- mac os x使用Git简易入门教程
该入门教程的流程是这样的: 什么是Git----------------->为什么选择Git----------------->如何安装Git到MAC OS X-------------- ...
- Gradle 简易入门教程
作者: Yann 来源:原力注入 Gradle 是一种构建工具,它抛弃了基于XML的构建脚本,取而代之的是采用一种基于 Groovy(现在也支持 Kotlin)的内部领域特定语言. Gradle特点 ...
- 最新翻译的官方PyTorch简易入门教程(PyTorch1.0版本)
"PyTorch 深度学习:60分钟快速入门"为PyTorch官网教程,网上已经有部分翻译作品,随着PyTorch1.0版本的公布,这个教程有较大的代码改动,本人对教程进行重新翻译 ...
- 【Magicavoxel简易入门教程】(二) 第二章 · 自制一个NPC导出模型优化工具使用(附下载)
本文由@唐三十胖子出品,转载请注明出处. 文章链接:https://blog.csdn.net/iceSony/article/details/83793754 这篇文章由唐三胖ヾ(•ω•`)o网 ...
- Xgboost简易入门教程
最近准备研究一下信贷风控中机器学习模型评分卡的制作.信贷评分卡分为两种,一种是用逻辑回归,称为评分卡:一种是用集成学习算法,称为机器学习模型.逻辑回归算法相对简单,但是解释性要求高:机器学习模型理 ...
最新文章
- orcale存储过程学习之路--创建空存储过程(二)
- mysql基础语法(常用)
- mybatis中去除多余的前缀或者后缀
- Java实现CSV读写操作源代码
- flask web开发的相关博文学习
- SpingBoot+Mybaits+Vue,更新学习
- SpringBoot热部署环境搭建和原理分析
- sklearn对三维矩阵降维代码实现
- oracle fopen函数,Utl_File.Fopen异常
- 迅雷精简版 for Mac 去除多余无用功能
- firefox改html内容,Firefox 中的 HTML5 音视频
- 什么是法线贴图 今天教你如何制作法线贴图
- 小米/红米手机刷第三方rom(红米5 plus为例)
- 概率论与数理统计学习笔记——第十八讲——二元随机变量分布函数、边际分布函数及条件分布函数
- js通过IP地址获取所在城市
- 雷达 -- 频谱历史介绍
- 关于电视机中DTV码流对android的Timer的影响
- 找出矩阵中的最大正方形
- matlab图形编辑,matlab绘制图形plot属性编辑
- 如何看服务器电源型号,AcBel CRPS 服务器电源系列介绍