STM32 —— Modbus 协议
STM32 —— Modbus 协议
Modbus 协议简介
Modbus 是一种串行通信协议,由于其协议简单易用,且没有版权要求,目前已经成为工业领域通信协议的实时标准。ModBus 协议是又施耐德电气的前身 Modicon 公司在 1979 年提出的。Modbus 目前有两个主要版本 ModBus串口,MODBUS TCP/IP
ModBus 串口又有两个变种:Modbus RTU 是一种紧凑的,采用二进制表示数据的方式,Modbus ASCII 是一种人类可读的,冗长的表示方式。还有一种扩展协议 MODBUS PLUS(Modbus+ 或者 MB+),不过此协议是 Modicon 专有的一种高速令牌传递网络,和 Modbus 不同,它需要一个专门的协处理器来处理类似 HDLC 的高速令牌旋转
Modbus 协议包括 RTU、ASCII、TCP,其中 Modbus-RTU 最常用,比较简单,在单片机上很容易实现。Modbus RTU 协议定义了一个与下层通信层无关的简单协议数据单元(PDU),串行链路上的 Modbus RTU 帧格式如下图所示
其中,地址字段只含有从机地址;功能码指示指令要执行何种操作;功能码的后续数据是请求或响应数据字段;差错检验字段是“报文内容”数据进行“循环冗余校验”计算所得结果,采用 CRC16 循环冗余校验算法
Modbus 和 OPC UA、MQTT 等通讯协议本质上是一样的,都是为了实现多个设备相互通信的应用层协议
协议内容介绍
Modbus 网络形式和协议
在介绍 Modbus 网络之前首先介绍一下 Modbus 网络上传输的是什么,和其他协议类似,Modbus 协议最基本的通信单位是帧,整个 Modbus 帧又被称之为应用数据单元(ADU),ADU 中又包含了协议数据单元(PDU)用于传真正需要传输的数据
Modbus 协议是一个主/从架构的协议。在同一个 Modbus 网络中同一时刻只有一个节点是主(master)节点,其他使用 Modbus 协议参与通信的节点是从(slave)节点,从节点的最大编号为 247 。每一个 slave 设备都有一个唯一的地址
在串行和 MB+ 网络中,通讯总是由主节点发起(在以太网上,任何一个设备都能发送一个 Modbus 命令,但是通常也只有一个主节点设备启动指令),子节点在没有收到主节点请求时不会发送数据。各个子节点之间不会直接相互通信
两种网络形式
在同一个时刻,主节点只会发起一个 Modbus 事务处理。什么是事务处理呢?其实就是一次网络上完整的应答通讯。主要包含两种形式,1 单播模式 , 2 广播模式
单播模式
所谓单播模式就是主节点给某个指定的节点发送消息(通过ADU中的地址域指定),从节点收到并处理完请求后,从节点向主节点返回一个应答报文,在这种模式下,一个 Modbus 事务包含两个报文,一个来自主节点的请求,一个来自子节点的应答
广播模式
所谓广播模式,是主节点向所有的子节点发送请求,当主节点发送的请求报文的地址域值为0时,代表广播请求,所有的从节点都需要接受处理,但不需要向主节点返回报文
双机通信原理
其实在物理层所有设备都会收到所有的请求,但地址域不为0时,从机判断当前为单播模式,只有地址域和自身地址号相同的从机才会响应请求,当地址域为0时,从机判断为广播消息,所有的从机都会执行指令,所有收到指令的设备都会运行,只不过不回应指令
客户机(主机)和服务器(从机)通信时会出现两种情况,一种是正常,一种是异常
其中事务处理正常时示意图如下,客户机(主机)向服务器(从机)发送请求,在功能码中填充功能码代号,说明服务器需要执行的动作,在数据码区填充具体的要求,比如读寄存器的地址和数量,通信正常时服务器会在返回的通信帧的功能码区中填充一个操作码,该操作码和功能码的值一样,在通讯帧的数据区填充返回的采样数据
当出现事务处理异常时,示意图如下,服务器会在返回的通讯帧的功能码中填充一个差错码,该差错码 = 功能码 + 0x80,即将功能码的最高位置1代表出现错误。并在后面的数据段中填充错误码,用来指示本次通信的错误具体内容
错误检测域是针对通讯链路是否可靠的检测域,通过CRC(循环冗余校验码)等错误校验方式校验通信过程中是否发生了差错
通信协议特点
Modbus 协议定义了一个控制器能够认识使用的消息结构,而不管它们是经过何种网络进行通信的。因此,底层通信方式可以使用 RS232,RS485 等串行链路,也可以使用 TCP/IP 以太网链路。当在 Modbus 网络上通信时,控制器必须要知道该网络中其他从设备的地址,才能识别按地址发来的消息,并作出相应行为。
简单来说,Modbus 通信协议具有以下几个特点:
Modbus 协议标准开放、公开发布且无版税要求,用户可以免费获取并使用 Modbus 协议,不需要缴纳许可证费;
Modbus 最开始使用 RS232,RS485 等串行链路作为底层通信方式,串行总线的接口芯片成本低,而且布线也简单方便;
Modbus 协议支持多种电气接口,如 RS232、RS485、TCP/IP 等,还可以在各种介质上传输,如双绞线、光纤、红外、无线等;
Modbus 是简单地应用层协议,其协议消息帧格式简单、紧凑、通俗易懂,便于用户理解和使用、厂商开发和集成,方便形成工业控制网络
帧详解
Modbus 协议的三种形式通讯的帧略有不同,具体如下:
MBAP 是一个通用的报文头,依赖于可靠的网络层,各域的典型长度如下(以串行链路为例)
地址域
第一部分是8位是地址域,用于给从机编号,而主机是没有地址的,从机的地址必须是唯一的。Modbus 地址域使用1个字节,寻址空间有 256 个不同地址,但合法的地址是 0 – 247
主节点通过将子节点的地址放到报文的地址域对子节点寻址。当子节点返回应答时, 它将自己的地址放到应答报文的地址域以让主节点知道哪个子节点在回答
功能码
第二部分 8 位是功能码,功能码指明服务器要执行的动作
主机通过在 PDU 中指定不同的功能码,通知从机(服务器)执行不同的动作, 功能码分为三类:
-
公共功能码:这是Modbus协议组织定义的功能码,被大家一致认可,普通情况下不会改变
-
用户定义功能码: 有两个用户定义功能码的定义范围,十进制 65 至 72 和十进制 100 至 110,可以用户自行定义使用
-
保留功能码:这是一些公司对一些历史产品使用的功能码,对公共来说是无效的
公共功能码的定义如下:
访问形式有单比特访问和16比特访问还有文件记录访问, 这里的线圈可以理解为开关量 0,1
数据区
介绍数据区之前,先介绍一下Mobbus协议的数据模型,Modbus 可访问的数据存储在四个区块或地址范围的其中一个: 线圈状态、离散量输入、保持寄存器和输入寄存器。这里的区块是概念性的定义,在物理层面它们可能作为独立的内存地址存在于给定的系统中,但也可能重叠,这个完全由设备自己管理
每个区块定义可以包含 65,536 个元素的地址空间。在 PDU 的定义中,Modbus 定义了每个数据元素的地址,范围从 0 到 65, 535 。但是我们的物理设备如寄存器、线圈通常从 1 开始编号从 1 到 n,其中 n 的最大值为 65,536。也就是说,线圈 11 位于地址 10 的线圈状态区块中,而保持寄存器 34 位于从机被定义为保持寄存器的内存部分中的地址 33。 实际使用时设备不会直接描述数据在某某号寄存器中,如电压量在第13号保存寄存器中,而是会描述为电压量在地址40001(或者4001,400001等),其中 4XXX、4XXXX 和 4XXXXX 的区别取决于设备使用的地址空间。 如果所有 65,536 个寄存器都在使用中,应该使用 4XXXXX 符号,因为其允许范围为 400,001~465,536。4 开头是因为实际使用时地址编码的前缀通常反映数据的类型,一般如下定义数据类型和前缀关系
错误检验域
该域是串行链路对报文内容执行 "冗余校验" 的计算结果。根据不同的传输模式 (RTU or ASCII)使用两种不同的计算方法
报文示例
请求读离散量输出 20-38 的实例
将输出 27-20 的状态表示为十六进制字节值 CD,或二进制 1100 1101。输出 27 是这个字节的 MSB,输出 20 是 LSB。按照惯例,将一个字节内的比特表示为 MSB 位于左侧,LSB 位于右侧。第一字节的输出从左至右为 27 至 20。下一个字节的输出从左到右为 35 至 28。当串行发射比特时,从 LSB 向 MSB 传输: 20 . . .27、28 . . . 35 等等。在最后的数据字节中,将输出状态 38-36 表示为十六进制字节值 05,或二进制 0000 0101。输出38 是左侧第六个比特位置,输出 36 是这个字节的 LSB。用零填充五个剩余高位比特。如果返回的输出数量不是八的倍数,将用零填充最后数据字节中的剩余比特。设备内部流程如下
异常代码
关于传输
串行传输模式有两种:RTU模式和ASCII模式
Modbus 串行链路 上所有设备的传输模式和串口参数必须相同。所有设备必须实现RTU模式,ASCII模式是选择项,只有配置成相同模式的设备才可以相互正常通信。在其他网络上(如MAP,Modbus Plus)Modbus 消息被转换为与串行传输无关的帧。Modbus 使用“大端模式”(big-Endian) 表示地址和数据项。当发送多个字节时,首先发送最高有效位。这是字节层面的,在串口线路中传送每个字节时 bit 传送模式为,LSB 先发送,MSB 后发送
RTU 传输模式
当控制器以 RTU 模式通信时,消息中每个 8bit 字节包含两个 4bit 十六进制字符。这种方式的有点是:在相同波特率下,可以比 ASCII 方式传送更多数据
相应的串口设置要求
1 起始位
8 数据位, 首先发送最低有效位
1 位作为奇偶校验
1 停止位
每个字符或字节均由此顺序发送(从左到右):最低有效位 (LSB) . . . 最高有效位 (MSB)
ASCII 传输模式
当 Modbus 串行链路的设备被配置为使用 ASCII (American Standard Code for Information Interchange) 模式通信时, 报文中的每个 8 位子节以两个 ASCII 字符发送。当通信链路或者设备无法符合 RTU 模式的定时管理时使用该模式
注 : 由于一个子节需要两个字符,此模式比 RTU 效率低
例 : 子节 0X5B 会被编码为两个字符 : 0x35 和 0x42 ( ASCII 编码 0x35 ="5", 0x42 ="B" )
相应的串口设置
1 起始位
7 数据位, 首先发送最低有效位
1 位作为奇偶校验
1 停止位
和RTU模式一样每个字符或字节均由此顺序发送(从左到右):最低有效位 (LSB) . . . 最高有效位 (MSB)
(ASCII 十六进制 3A )起始,以‘回车-换换行’ (CR LF) 对(ASCII 十六进制 0D 和 0A)结束
应用场景
ModBus 协议可以解决工厂不同种类设备的数据采集问题,使得我们可以通过采集的数据随时监控工厂的运行情况。MODBUS 协议允许在各种网络体系结构内进行简单通信,它的常见体系结构图如下
HMI 代表人机界面,PLC 是工厂常用的采集设备,工厂中的各类 PLC,I/O 数据接口,驱动器设备可以通过各类 Modbus 协议采集它的数据,并且不同 Modbus 协议网络之间还可以通过网关进行数据交换