MODBUS总线的学习笔记

MODBUS学习记录

下面所有资料均copy于安富莱电子和博客中,仅作为个人学习笔记记录,写的不好请见谅。

1.modbus简介介绍

Modbus 是由 Modicon(现为施耐德电气公司的一个品牌)在 1979 年发明的,是全球第一个真正 用于工业现场的总线协议。 ModBus 网络是一个工业通信系统,由带智能终端的可编程序控制器和计算机通过公用线路或局部专
用线路连接而成。其系统结构既包括硬件、亦包括软件。它可应用于各种数据采集和过程监控。 为更好地普及和推动Modbus 在基于以太网上的分布式应用,目前施耐德公司已将Modbus 协议的
所有权移交给 IDA(Interface for Distributed Automation,分布式自动化接口)组织,并成立了 Modbus-IDA组织,为Modbus 今后的发展奠定了基础。 在中国,Modbus 已经成为国家标准。 标准编号:GB/T19582-2008 标准名称:《基于Modbus 协议的工业自动化网络规范》 分 3 个部分:

  • 《GB/T 19582.1-2008 第 1 部分:Modbus 应用协议》
  • 《GB/T 19582.2-2008 第 2 部分:Modbus 协议在串行链路上的实现指南》
  • 《GB/T 19582.3-2008 第 3 部分: Modbus 协议在 TCP/IP 上的实现指南》

modbus协议层模型

modbus的7层osi模型中,只有物理层和数据链路层和应用层。

Modbus 串行链路协议是一个主/从协议。该协议位于OSI 模型的第二层。

一个主从类型的系统有一个向某个“子”节点发出显式命令并处理响应的节点(主节点)。典型的子节 点在没有收到主节点的请求时并不主动发送数据,也不与其它子节点通信。 在物理层,Modbus 串行链路系统可以使用不同的物理接口(RS485、RS232)。最常用的是
TIA/EIA-485 (RS485) 两线制接口。

image-20211008092937631

modbus主/从协议的原理

Modbus 串行链路协议是一个主-从协议。在同一时刻,只有一个主节点连接于总线,一个或多个子 节点 (最大编号为 247 ) 连接于同一个串行总线。通信时,总是由主站发起,在从站没有收到来着主站的请求时,不会发送数据,并且从站之间不会互相通信。

主站可以对从站发起下面两种请求:
  • 单播模式

    主节点以特定地址访问某个子节点,子节点接到并处理完请求后,子节点向主节点返回一个报文(一个 ‘应答’)。在这种模式,一个 Modbus 事务处理包含 2 个报文:一个来自主节点的请求,一个来自子节 点的应答。
    每个子节点必须有唯一的地址 (1 到 247),这样才能区别于其它节点被独立的寻址。

  • 广播模式

    主节点向所有的子节点发送请求。对于主节点广播的请求没有应答返回。广播请求一般用于写命令。 所有设备必须接受广播模式的写功能。地址 0 是专门用于表示广播数据的。

modbus地址规则

Modbus 寻址空间有 256 个不同地址。

地址 0 为广播地址。所有的子节点必须识别广播地址。 Modbus 主节点没有地址,只有子节点必须有一个地址。 该地址必须在 Modbus 串行总线上唯一。

modbus的帧概述

image-20211013191821174

在modbus串行链路中,地址域只有子节点的地址,合法的子节点地址为十进制0-247,每个子设备被赋予1-247范围中的地址,地址0用来广播。

RTU传输模式

有两种串行传输模式被定义: RTU 模式 和 ASCII 模式。(常用RTU模式)

它定义了报文域的位内容在线路上串行的传送。它确定了信息如何打包为报文和解码。

尽管在特定的领域 ASCII 模式是要求的,但达到 Modbus 设备之间的互操作性只有每个设备都有 相同的模式: 所有设备必须实现 RTU 模式。ASCII 传输模式是选项。

这种模式的主要优点是较高的数据密度,在相同的波特率下比ASCII 模式有更 高的吞吐率。

RTU模式每个字节 ( 11 位 ) 的格式为 :

编码系统: 8–位二进制,报文中每个 8 位字节含有两个 4 位十六进制字符(0–9, A–F)

1个起始位,8个数据位,1个奇偶校验位,一个停止位。

偶校验是要求的, 其它模式 ( 奇校验, 无校验 ) 也可以使用。 为了保证与其它产品的最大兼容性, 同时支持无校验模式是建议的。默认校验模式模式 必须为偶校验。
注 : 使用无校验要求2 个停止位。

在代码中看到串口的配置,是1个起始位,8个数据位,没有校验位,一个停止位,也没搞懂,应该来说是两个校验位。

image-20211013192329341

MODBUS DTU帧描述:

image-20211013193738320

在 RTU 模式,报文帧由时长至少为 3.5 个字符时间的空闲间隔区分。在后续的部分,这个时间区间 被称作 t3.5

image-20211013193909888

整个报文帧必须以连续的字符流发送。 如果两个字符之间的空闲间隔大于 1.5 个字符时间,则报文帧被认为不完整应该被接收节点丢弃。

image-20211013193930332

英语,t1.5和t3.5的定时,存在着大量的中断,在高速通信的情况下,增加cpu负担,因此在速率等于或者低于19200bps时,这两个定时必须严格遵守; 对于波特率大于 19200 bps 的情形,应该使用 2 个定时的固定值:

  • 建议的字符间超时时间(t1.5)为 750µs,
  • 帧间的超时时间 (t1.5) 为 1.750ms。

在代码中,没有看到t1,5的定时,只有看到了t3.5每个帧之间的间隔,也可能没看仔细…

更新:一般串口就已满足,不需要t1.5定时。

RTU传输模式状态图

image-20211013194326796

CRC 校验

在 RTU 模式包含一个对全部报文内容执行的,基于循环冗余校验 (CRC - Cyclical RedundancyChecking) 算法的错误检验域。CRC 域检验整个报文的内容。不管报文有无奇偶校验,均执行此检验。 CRC 包含由两个 8 位字节组成的一个 16 位值。 CRC 域作为报文的最后的域附加在报文之后。计算后,首先附加低字节,然后是高字节。CRC 高字
节为报文发送的最后一个子节。 附加在报文后面的 CRC 的值由发送设备计算。接收设备在接收报文时重新计算 CRC 的值,并将计
算结果于实际接收到的CRC 值相比较。如果两个值不相等,则为错误。 CRC 的计算, 开始对一个 16 位寄存器预装全1。 然后将报文中的连续的 8 位子节对其进行后续的计
算。只有字符中的 8 个数据位参与生成CRC 的运算,起始位,停止位和校验位不参与 CRC 计算。 CRC 的生成过程中, 每个 8–位字符与寄存器中的值异或。然后结果向最低有效位(LSB)方向移动
(Shift) 1 位,而最高有效位(MSB)位置充零。 然后提取并检查 LSB:如果 LSB 为 1, 则寄存器中的值与 一个固定的预置值异或;如果 LSB 为 0, 则不进行异或操作。 这个过程将重复直到执行完 8 次移位。完成最后一次(第 8 次)移位及相关操作后,下一个 8 位字节
与寄存器的当前值异或,然后又同上面描述过的一样重复 8 次。当所有报文中子节都运算之后得到的寄存
器忠的最终值,就是 CRC。

ASCII传输模式

当 Modbus 串行链路的设备被配置为使用 ASCII (American Standard Code for Information Interchange) 模式通信时, 报文中的每个 8 位子节以两个 ASCII 字符发送。当通信链路或者设备无法 符合 RTU 模式的定时管理时使用该模式。

注 : 由于一个子节需要两个字符,此模式比 RTU 效率低。
例 : 子节 0X5B 会被编码为两个字符 : 0x35 和 0x42 ( ASCII 编码0x35 =“5”, 0x42 =“B” )。

ASCII 模式每个字节 ( 10 位 ) 的格式为 : 编码系统: 十六进制,ASCII 字符 0-9, A-F。报文中每个ASCII 字符含有 1 个十六进制字符 Bits per Byte: 1起始位 7数据位(首先发送最低有效位) 1位作为奇偶校验 1停止位

偶校验是要求的, 其它模式 ( 奇校验, 无校验 ) 也可以使用。 为了保证与其它产品的最大兼容性, 同时支持无校验模式是建议的。默认校验模式模式 必须为偶校验。
注 : 使用无校验要求 2 个停止位。

image-20211013201051135

Modbus ASCII 报文帧

由发送设备将 Modbus 报文构造为带有已知起始和结束标记的帧。这使设备可以在报文的开始接收 新帧,并且知道何时报文结束。不完整的报文必须能够被检测到而错误标志必须作为结果被设置。 报文帧的地址域含有两个字符。

在 ASCII 模式, 报文用特殊的字符区分帧起始和帧结束。一个报文必须以一个‘冒号’ ( : ) (ASCII
十六进制 3A )起始,以 ‘回车-换行’ (CR LF) 对 (ASCII 十六进制 0D 和 0A) 结束。

注 : LF 字符可以通过特定的Modbus 应用命令 (参见 Modbus 应用协议规范) 改变。

对于所有的域,允许传送的字符为十六进制 0–9, A–F (ASCII 编码)。 设备连续的监视总线上的 ‘冒
号’ 字符。 当收到这个字符后,每个设备解码后续的字符一直到帧结束。
报文中字符间的时间间隔可以达一秒。如果有更大的间隔,则接受设备认为发生了错误。

下图显示了一个典型的报文帧。

image-20211013201408419

注:每个字符子节需要用两个字符编码。因此,为了确保 ASCII 模式 和 RTU 模式在 Modbus 应 用级兼容,ASCII 数据域最大数据长度为 (2x252) 是 RTU 数据域 (252) 的两倍。
必然的, Modbus ASCII 帧的最大尺寸为513 个字符。

ASCII传输模式状态图

image-20211013201540078

LRC 校验

在 ASCII 模式,包含一个对全部报文内容执行的,基于纵向冗余校验 (LRC - Longitudinal Redundancy Checking) 算法的错误检验域。LRC 域检验不包括起始“冒号”和结尾 CRLF 对的整个报 文的内容。不管报文有无奇偶校验,均执行此检验。

LRC 域为一个子节,包含一个 8 位二进制值。LRC 值由发送设备计算,然后将 LRC 附在报文后面。
接收设备在接收报文时重新计算 LRC 的值,并将计算结果于实际接收到的LRC 值相比较。如果两个值不 相等,则为错误。

LRC 的计算, 对报文中的所有的连续 8 位字节相加,忽略任何进位,然后求出其二进制补码。执行检
验针对不包括起始“冒号”和结尾 CRLF 对的整个 ASCII 报文域的内容。在 ASCII 模式, LRC 的结果
被ASCII 编码为两个字节并放置于ASCII 模式报文帧的结尾, CRLF 之前。

modbus事物处理的流程

image-20211013202700159

异常码定义

下面是异常码的表格

image-20211013203309630

2.1功能码定义

功能码分类

有三类MODBUS 功能码。它们是:公共功能码用户定义功能码保留功能码

image-20211018091625524

公共功能码定义

  • 是较好地被定义的功能码,
  • 保证是唯一的,
  • MODBUS 组织可改变的,
  • 公开证明的,
  • 具有可用的一致性测试,
  • MB IETF RFC中证明的,
  • 包含已被定义的公共指配功能码和未来使用的未指配保留供功能码。

用户定义功能码

  • 有两个用户定义功能码的定义范围,即 65 至 72 和十进制 100 至 110。
  • 用户没有MODBUS 组织的任何批准就可以选择和实现一个功能码
  • 不能保证被选功能码的使用是唯一的。
  • 如果用户要重新设置功能作为一个公共功能码,那么用户必须启动 RFC,以便将改变引入公共分
    类中,并且指配一个新的公共功能码。

保留功能码

  • 一些公司对传统产品通常使用的功能码,并且对公共使用是无效的功能码。

2.2 公共功能码定义

实际上常用的功能码就:01, 02, 03, 04, 05, 15, 16.

image-20211018092014750

下面是01H的介绍,其他功能码用到时再看就行,实际也是对着产品的协议来的,没必要牢记。

image-20211018092324229

RTU主从协议栈实现

从机框架图

image-20230124103831773

image-20230124103909561

不管数据对错都要应答回复。

主要就是要实现串口的接收,并且硬件的微秒级定时器实现字符超时判断;然后再实现串口发送即可;然后就是数据解析部分;

然后采用RTU的硬件配置下,要对串口进行相对应的配置。

image-20230124104735796

采用无奇偶校验位如下

image-20230124104907136

这里要注意,数据部分是大端格式,需要进行转化,crc是小端,直接默认即可。因为arm类是小端格式

image-20230124183406979

软件部分

下面是串口的结构体抽象,后面几个就是与485相关的,其他的是跟串口FIFO实现有关。

如:SendOver和SendBefore函数指针,就是实现485芯片的接收和发送的使能。ReceiveNew实现新的字节数据的接收。

image-20230124105142432

如下就是485芯片的收发模式切换的函数。

image-20230124105516957

下面是在中断函数中用回调函数实现MODBUS数据的接收。

image-20230124105813809

后面就是数据接收和字符超时的判断。

image-20230124144258408

image-20230124144429079

超过间隔时间以后,开始判断,如果小于最基本的4个字节则判断错误,然后计算CRC校验和,如果接收正常则为0。然后判断数据的中的地址是否符合,最后开始应用层的数据解析即可。

image-20230124152618283

image-20230124152825116

从机框架图

和从机差不多,主要也是在接收部分,发送部分很简单。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fU8GZnKm-1674563529852)(http://os.zhengshijian.com//img/%E5%BE%AE%E4%BF%A1%E6%88%AA%E5%9B%BE_20230124191829.png)]

image-20230124190502365

image-20230124190533449

代码

下面给出例程代码,不管是跑裸机还上RTOS,只需把例程中的代码移植一下,非常简单。

链接:https://pan.baidu.com/s/1fwrP2Np5PnqytU3q_by1iw
提取码:u16s
–来自百度网盘超级会员V5的分享

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
freemodbus 是一款开源的Modbus通信协议栈,用于实现Modbus通信协议的开发。通过学习freemodbus,我收获了许多知识和技能。 首先,在学习freemodbus时,我了解到了Modbus通信协议的基本原理和工作方式。Modbus是一种常用的串行通信协议,主要用于工业自动化领域中设备之间的通信。它使用简单的请求-响应机制进行数据传输,包括读取和写入寄存器等功能。通过freemodbus学习,我了解到了Modbus通信协议的组成结构、数据帧格式以及常用的功能码等。 其次,通过实践freemodbus的使用,我学会了如何在嵌入式系统中实现Modbus通信功能。freemodbus提供了一系列的接口函数,可以方便地实现Modbus主站和从站的功能,并支持多种串口通信方式,如RS485、TCP等。学习过程中,我熟悉了freemodbus的API函数的使用方法,掌握了创建、初始化和配置Modbus通信对象的技巧。 另外,通过使用freemodbus,我学到了一些调试和排错的技巧。在实际应用中,由于硬件、软件等多种因素的影响,可能会出现通信故障或数据错误的情况。通过freemodbus的调试工具和相关的日志输出,我学会了如何在开发过程中定位和解决各种问题,提高了软件开发的技能和经验。 总体来说,学习freemodbus是一次非常有益的经历。通过这个学习过程,我不仅掌握了Modbus通信协议的原理和应用,还提高了嵌入式软件开发的能力。我相信,在今后的工作中,我可以更好地应用freemodbus开发各种工业自动化设备和系统。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

炒饭多加个蛋

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

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

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

打赏作者

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

抵扣说明:

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

余额充值