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) 两线制接口。
modbus主/从协议的原理
Modbus 串行链路协议是一个主-从协议。在同一时刻,只有一个主节点连接于总线,一个或多个子 节点 (最大编号为 247 ) 连接于同一个串行总线。通信时,总是由主站发起,在从站没有收到来着主站的请求时,不会发送数据,并且从站之间不会互相通信。
主站可以对从站发起下面两种请求:
-
单播模式
主节点以特定地址访问某个子节点,子节点接到并处理完请求后,子节点向主节点返回一个报文(一个 ‘应答’)。在这种模式,一个 Modbus 事务处理包含 2 个报文:一个来自主节点的请求,一个来自子节 点的应答。
每个子节点必须有唯一的地址 (1 到 247),这样才能区别于其它节点被独立的寻址。 -
广播模式
主节点向所有的子节点发送请求。对于主节点广播的请求没有应答返回。广播请求一般用于写命令。 所有设备必须接受广播模式的写功能。地址 0 是专门用于表示广播数据的。
modbus地址规则
Modbus 寻址空间有 256 个不同地址。
地址 0 为广播地址。所有的子节点必须识别广播地址。 Modbus 主节点没有地址,只有子节点必须有一个地址。 该地址必须在 Modbus 串行总线上唯一。
modbus的帧概述
在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个数据位,没有校验位,一个停止位,也没搞懂,应该来说是两个校验位。
MODBUS DTU帧描述:
在 RTU 模式,报文帧由时长至少为 3.5 个字符时间的空闲间隔区分。在后续的部分,这个时间区间 被称作 t3.5。
整个报文帧必须以连续的字符流发送。 如果两个字符之间的空闲间隔大于 1.5 个字符时间,则报文帧被认为不完整应该被接收节点丢弃。
英语,t1.5和t3.5的定时,存在着大量的中断,在高速通信的情况下,增加cpu负担,因此在速率等于或者低于19200bps时,这两个定时必须严格遵守; 对于波特率大于 19200 bps 的情形,应该使用 2 个定时的固定值:
- 建议的字符间超时时间(t1.5)为 750µs,
- 帧间的超时时间 (t1.5) 为 1.750ms。
在代码中,没有看到t1,5的定时,只有看到了t3.5每个帧之间的间隔,也可能没看仔细…
更新:一般串口就已满足,不需要t1.5定时。
RTU传输模式状态图
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 个停止位。
Modbus ASCII 报文帧
由发送设备将 Modbus 报文构造为带有已知起始和结束标记的帧。这使设备可以在报文的开始接收 新帧,并且知道何时报文结束。不完整的报文必须能够被检测到而错误标志必须作为结果被设置。 报文帧的地址域含有两个字符。
在 ASCII 模式, 报文用特殊的字符区分帧起始和帧结束。一个报文必须以一个‘冒号’ ( : ) (ASCII
十六进制 3A )起始,以 ‘回车-换行’ (CR LF) 对 (ASCII 十六进制 0D 和 0A) 结束。
注 : LF 字符可以通过特定的Modbus 应用命令 (参见 Modbus 应用协议规范) 改变。
对于所有的域,允许传送的字符为十六进制 0–9, A–F (ASCII 编码)。 设备连续的监视总线上的 ‘冒
号’ 字符。 当收到这个字符后,每个设备解码后续的字符一直到帧结束。
报文中字符间的时间间隔可以达一秒。如果有更大的间隔,则接受设备认为发生了错误。
下图显示了一个典型的报文帧。
注:每个字符子节需要用两个字符编码。因此,为了确保 ASCII 模式 和 RTU 模式在 Modbus 应 用级兼容,ASCII 数据域最大数据长度为 (2x252) 是 RTU 数据域 (252) 的两倍。
必然的, Modbus ASCII 帧的最大尺寸为513 个字符。
ASCII传输模式状态图
LRC 校验
在 ASCII 模式,包含一个对全部报文内容执行的,基于纵向冗余校验 (LRC - Longitudinal Redundancy Checking) 算法的错误检验域。LRC 域检验不包括起始“冒号”和结尾 CRLF 对的整个报 文的内容。不管报文有无奇偶校验,均执行此检验。
LRC 域为一个子节,包含一个 8 位二进制值。LRC 值由发送设备计算,然后将 LRC 附在报文后面。
接收设备在接收报文时重新计算 LRC 的值,并将计算结果于实际接收到的LRC 值相比较。如果两个值不 相等,则为错误。
LRC 的计算, 对报文中的所有的连续 8 位字节相加,忽略任何进位,然后求出其二进制补码。执行检
验针对不包括起始“冒号”和结尾 CRLF 对的整个 ASCII 报文域的内容。在 ASCII 模式, LRC 的结果
被ASCII 编码为两个字节并放置于ASCII 模式报文帧的结尾, CRLF 之前。
modbus事物处理的流程
异常码定义
下面是异常码的表格
2.1功能码定义
功能码分类
有三类MODBUS 功能码。它们是:公共功能码、用户定义功能码、保留功能码。
公共功能码定义
- 是较好地被定义的功能码,
- 保证是唯一的,
- MODBUS 组织可改变的,
- 公开证明的,
- 具有可用的一致性测试,
- MB IETF RFC中证明的,
- 包含已被定义的公共指配功能码和未来使用的未指配保留供功能码。
用户定义功能码
- 有两个用户定义功能码的定义范围,即 65 至 72 和十进制 100 至 110。
- 用户没有MODBUS 组织的任何批准就可以选择和实现一个功能码
- 不能保证被选功能码的使用是唯一的。
- 如果用户要重新设置功能作为一个公共功能码,那么用户必须启动 RFC,以便将改变引入公共分
类中,并且指配一个新的公共功能码。
保留功能码
- 一些公司对传统产品通常使用的功能码,并且对公共使用是无效的功能码。
2.2 公共功能码定义
实际上常用的功能码就:01, 02, 03, 04, 05, 15, 16.
下面是01H的介绍,其他功能码用到时再看就行,实际也是对着产品的协议来的,没必要牢记。
RTU主从协议栈实现
从机框架图
不管数据对错都要应答回复。
主要就是要实现串口的接收,并且硬件的微秒级定时器实现字符超时判断;然后再实现串口发送即可;然后就是数据解析部分;
然后采用RTU的硬件配置下,要对串口进行相对应的配置。
采用无奇偶校验位如下
这里要注意,数据部分是大端格式,需要进行转化,crc是小端,直接默认即可。因为arm类是小端格式
软件部分
下面是串口的结构体抽象,后面几个就是与485相关的,其他的是跟串口FIFO实现有关。
如:SendOver和SendBefore函数指针,就是实现485芯片的接收和发送的使能。ReceiveNew实现新的字节数据的接收。
如下就是485芯片的收发模式切换的函数。
下面是在中断函数中用回调函数实现MODBUS数据的接收。
后面就是数据接收和字符超时的判断。
超过间隔时间以后,开始判断,如果小于最基本的4个字节则判断错误,然后计算CRC校验和,如果接收正常则为0。然后判断数据的中的地址是否符合,最后开始应用层的数据解析即可。
从机框架图
和从机差不多,主要也是在接收部分,发送部分很简单。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fU8GZnKm-1674563529852)(http://os.zhengshijian.com//img/%E5%BE%AE%E4%BF%A1%E6%88%AA%E5%9B%BE_20230124191829.png)]
代码
下面给出例程代码,不管是跑裸机还上RTOS,只需把例程中的代码移植一下,非常简单。
链接:https://pan.baidu.com/s/1fwrP2Np5PnqytU3q_by1iw
提取码:u16s
–来自百度网盘超级会员V5的分享