1、 Modbus简介
Modbus 是由 Modicon(现为施耐德电气公司的一个品牌)在 1979 年发明的,是全球第一个真正 用于工业现场的总线协议。ModBus 网络是一个工业通信系统,由带智能终端的可编程序控制器和计算机通过公用线路或局部专 用线路连接而成。其系统结构既包括硬件、亦包括软件。它可应用于各种数据采集和过程监控。为更好地普及和推动 Modbus 在基于以太网上的分布式应用,目前施耐德公司已将 Modbus 协议的 所有权移交给 IDA(Interface for Distributed Automation,分布式自动化接口)组织,并成立了 Modbus-IDA 组织,为 Modbus 今后的发展奠定了基础。
在中国,Modbus 已经成为国家标准,并有专业的规范文档,感兴趣的可以去查阅相关的文件,详情如下:标准编号为:GB/T19582-2008文件名称:《基于 Modbus 协议的工业自动化网络规范》
主要有三部分的内容,分别如下:
《GB/T 19582.1-2008 第 1 部分:Modbus 应用协议》
《GB/T 19582.2-2008 第 2 部分:Modbus 协议在串行链路上的实现指南》
《GB/T 19582.3-2008 第 3 部分: Modbus 协议在 TCP/IP 上的实现指南》
2、Modbus协议概述
Modbus是一个主-从模式的通信协议,属于数据链路层上的协议,协议本身不涉及具体的硬件要求。常见的应用Modbus协议的物理接口有RS-485、RS232、USART等的通信链路中。Modbus协议中,一个时刻内只允许有一个主机连接于总线,多个从机连接于总线上,通信都是只能由主机发起,从机进行响应。不能从从机主动发起通信。
3、Modbus 主从机通信模式
主机和从机之间的通信,可以用两种模式进行:广播通知模式、单播点对点模式。
3.1、单播点对点模式
主机按照从机的明确地址访问相应的从机,从机接到来自主机的请求并处理完请求后,从机会向主机返回一个应答,完成一个通信。在这种模式,一个 Modbus 事务处理包含 2 个报文:一个来自主机的请求,一个来自从机的应答。在总线上,每个从机都必须有唯一的从机地址 (1 到 247),这样才能区别于其它节点被独立的寻址。
3.2、广播通知模式
主机向所总线通过广播指令发送请求,所有的从机都要接收来自主机的广播信息。对于主机广播的请求,从机是没有应答返回的。所有的从机必须要接受主机的广播模写功能。注意:地址 0 是专门用于主机向各个从机广播数据的。
4、Modbus 地址规则
Modbus 寻址空间有 256 个不同地址。如下图所示:
地址 0 为广播地址。所有的从机必须识别广播地址。Modbus 主机本身是没有地址的,只有从机必须要有一个地址。该地址必须在 Modbus 串行总线上唯一。248~255作为预留使用的地址。
5、Modbus 的帧格式
Modbus的帧格式按照选择的模式不同帧格式也是有所区别的。
5.1、RTU模式
RTU 模式下的帧格式如下图:
Modbus RTU 帧总长度最大为 256 字节。RTU 模式每个字节 ( 11 位 ) 的格式为 :8–位二进制,报文中每个 8 位字节含有两个 4 位十六进制字符(0–9, A–F)每字节的 bit 流:1 起始位8 数据位, 首先发送最低有效位1 位作为奇偶校验1 停止位偶校验是要求的, 其它模式 ( 奇校验, 无校验 ) 也可以使用。为了保证与其它产品的最大兼容性, 同时支持无校验模式是建议的。默认校验模式模式 必须为偶校验。注 : 使用无校验要求 2 个停止位。RTU时,每个字符或字节均由此顺序发送(从左到右):
最低有效位 (LSB) . . . 最高有效位 (MSB)
5.1.1、RTU模式下的帧通信
由发送设备将 Modbus 报文构造为带有已知起始和结束标记的帧。这使设备可以在报文的开始接收 新帧,并且知道何时报文结束。不完整的报文必须能够被检测到而错误标志必须作为结果被设置。在 RTU 模式,报文帧由时长至少为 3.5 个字符时间的空闲间隔区分。
整个报文帧必须以连续的字符流发送。如果两个字符之间的空闲间隔大于 1.5 个字符时间,则报文帧被认为不完整应该被接收节点丢弃。
注意 :RTU 模式下接收数据时,由于 t1.5 和 t3.5 的时间隔要求的存在,一般在高通信速率下,会导致 CPU 负担加重。因此,在通信速率等于或低于 19200 bps 时,这两个定时必须严格遵守;对于波特率大于 19200 bps 的情形,应该使用 2 个定时的固定值:建议的字符间超时时间(t1.5)为 750µs,帧间的超时时间 (t1.5) 为 1.750ms。下图表示了对 RTU 传输模式状态图的描述。”主节点” 和 “子节点” 的不同角度均在相同的图中表示:
上面状态图的一些解释:
1)从 “初始” 态到 “空闲” 态转换需要 t3.5 定时超时: 这保证帧间延迟
2)“空闲” 态是没有发送和接收报文要处理的正常状态。
3)在 RTU 模式, 当没有活动的传输的时间间隔达 3.5 个字符长时,通信链路被认为在 “空闲” 态。
4)当链路空闲时, 在链路上检测到的任何传输的字符被识别为帧起始。链路变为 “活动” 状态。然后当链路上没有字符传输的时间间个达到 t3.5 后,被识别为帧结束。
5)检测到帧结束后,完成 CRC 计算和检验。然后,分析地址域以确定帧是否发往此设备,如果不是, 则丢弃此帧。为了减少接收处理时间,地址域可以在一接到就分析,而不需要等到整个帧结束。这 样,CRC 计算只需要在帧寻址到该节点 (包括广播帧) 时进行。
5.1.2、RTU模式的CRC校验
在 RTU 模式包含一个对全部报文内容执行的,基于循环冗余校验 (CRC – Cyclical Redundancy Checking) 算法的错误检验域。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。
5.2、ASCII传输模式
当 Modbus 串行链路的设备被配置为使用 ASCII模式通信时,报文中的每个 8 位字节以两个 ASCII 字符发送。一般在通信链路或者设备无法 符合 RTU 模式的定时管理时使用该模式。ASCII的帧格式如下:
比如 : 字节 0X5B 会被编码为两个字符 : 0x35 和 0x42 ( ASCII 编码 0x35 =”5″, 0x42 =”B” )。注 : 由于一个子节需要两个字符,此模式比 RTU 效率低。
ASCII 模式每个字节 ( 10 位 ) 的格式为 :十六进制,ASCII 字符 0-9, A-F。1 起始位7 数据位, 首先发送最低有效位1 位作为奇偶校验1 停止位偶校验是要求的, 其它模式 ( 奇校验, 无校验 ) 也可以使用。为了保证与其它产品的最大兼容性, 同时支持无校验模式是建议的。默认校验模式模式 必须为偶校验。注 : 使用无校验要求 2 个停止位。字符是如何串行传送的:每个字符或字节均由此顺序发送(从左到右):
最低有效位 (LSB) . . . 最高有效位 (MSB)
5.2.1、ASCII的报文帧
在 ASCII 模式, 报文用特殊的字符区分帧起始和帧结束。一个报文必须以一个‘冒号’ ( : ) (ASCII 十六进制 3A )起始,以 ‘回车-换行’ (CR LF) 对 (ASCII 十六进制 0D 和 0A) 结束。注 : LF 字符可以通过特定的 Modbus 应用命令 (参见 Modbus 应用协议规范) 改变。对于所有的域,允许传送的字符为十六进制 0–9, A–F (ASCII 编码)。设备连续的监视总线上的 ‘冒 号’ 字符。当收到这个字符后,每个设备解码后续的字符一直到帧结束。报文中字符间的时间间隔可以达一秒。如果有更大的间隔,则接受设备认为发生了错误。特别注意:每个字符子节需要用两个字符编码。因此,为了确保 ASCII 模式 和 RTU 模式在 Modbus 应 用级兼容,ASCII 数据域最大数据长度为 (2×252) 是 RTU 数据域 (252) 的两倍。必然的, Modbus ASCII 帧的最大尺寸为 513 个字符。ASCII 报文帧的要求在下面的状态图中综合。”主节点” 和 “子节点” 的不同角度均在相同的图中表示:
上面状态图的一些解释:1)“空闲” 态是没有发送和接收报文要处理的正常状态。2)每次接收到 “:” 字符表示新的报文的开始。如果在一个报文的接收过程中收到该字符,则当前地报文 被认为不完整并被丢弃。而一个新的接收缓冲区被重新分配。3)检测到帧结束后,完成 LRC 计算和检验。然后,分析地址域以确定帧是否发往此设备,如果不是, 则丢弃此帧。为了减少接收处理时间,地址域可以在一接到就分析,而不需要等到整个帧结束。
5.2.2、ASCII的LRC校验
在 ASCII 模式,包含一个对全部报文内容执行的,基于纵向冗余校验 (LRC – Longitudinal Redundancy Checking) 算法的错误检验域。LRC 域检验不包括起始“冒号”和结尾 CRLF 对的整个报 文的内容。不管报文有无奇偶校验,均执行此检验。LRC 域为一个子节,包含一个 8 位二进制值。LRC 值由发送设备计算,然后将 LRC 附在报文后面。接收设备在接收报文时重新计算 LRC 的值,并将计算结果于实际接收到的 LRC 值相比较。如果两个值不 相等,则为错误。LRC 的计算, 对报文中的所有的连续 8 位字节相加,忽略任何进位,然后求出其二进制补码。执行检 验针对不包括起始“冒号”和结尾 CRLF 对的整个 ASCII 报文域的内容。在 ASCII 模式,LRC 的结果 被 ASCII 编码为两个字节并放置于 ASCII 模式报文帧的结尾,CRLF 之前。
6、Modbus的异常码
MODBUS 事务处理的一般处理过程:
一旦服务器处理请求,使用合适的 MODBUS 服务器事务建立 MODBUS 响应。根据处理结果,可以建立两种类型响应:
1) 一个正确的 MODBUS 响应:响应功能码 = 请求功能码
2) 一个 MODBUS 异常响应
3)用来为客户机提供处理过程中与被发现的差错相关的信息;
4)响应功能码 = 请求功能码 + 0x80;
5)提供一个异常码来指示差错原因。
7、Modbus的功能码
7.1、功能码的类别
目前Modbus的功能中可以分为三类:公共功能码、用户定义功能码、保留功能码。
公共功能码 :是已经被定义的功能码。
用户定义功能码 :有两个可以由用户定义功能码。范围为:65 至 72 和十进制 100 至 110。
保留功能码 :特殊情况下使用的,并且对公共使用是无效的功能码。
7.2、公共功能码
Modbus中公共功能码的定义如下:
7.2.1、线圈操作功能码(bit位的操作)
比如我要读取线圈中的内容。从机地址为 11H,线圈寄存器的起始地址为 0013H,结束地址为 0037H。需要查询总共 37 个线圈寄存器,主机发送的RTU帧如下:
从机响应的数据帧如下:
解析:线圈 0013H 到线圈 001AH 的状态为 CDH,二进制值为 11001101,该字节的最高字节为线圈 001AH , 最 低 字 节 为 线 圈 0013H 。各线圈状态与数据内容每位相对应。1 代表 ON,0 代表 OFF。线 圈 001AH 到 线 圈 0013H 的 状态分别为:
7.2.2、保持寄存器操作功能码
(1)写多个保持寄存器
写多个保持寄存器使用功能码10H。比如:从机地址为 11H。保持寄存器的其实地址为 0001H,寄存器的结束地址为 0002H。总共访问 2个寄存器。保持寄存器 0001H 的内容为 000AH,保持寄存器 0002H 的内容为 0102H。
主机请求的RTU帧数据如下:
从机返回的响应为:
(2)读保持寄存器
读保持寄存器使用03H功能码。比如:从机地址为 11H。保持寄存器的起始地址为 006BH,结束地址为 006DH。
主机发送的RTU请求帧如下:
从机的应答如下: