1、 Modbus简介
Modbus 是由 Modicon(现为施耐德电气公司的一个品牌)在 1979 年发明的,是全球第一个真正 用于工业现场的总线协议。ModBus 网络是一个工业通信system,由带智能终端的可编程序控制器和计算机通过公用线路或局部专 用线路connect而成。其system结构既包括硬件、亦包括软件。它可应用于各种Data Acquisition和过程监控。为更好地普及和推动 Modbus 在基于以太网上的分布式应用,目前施耐德公司已将 Modbus protocol的 所有权移交给 IDA(Interface for Distributed Automation,分布式自动化接口)组织,并成立了 Modbus-IDA 组织,为 Modbus 今后的发展奠定了基础。
在中国,Modbus 已经成为国家标准,并有专业的Specifications,感兴趣的可以去查阅Related的文件,详情如下:标准编号为:GB/T19582-2008文件名称:《基于 Modbus protocol的Automation网络规范》
主要有三部分的内容,分别如下:
《GB/T 19582.1-2008 第 1 部分:Modbus 应用协议》
《GB/T 19582.2-2008 第 2 部分:Modbus protocol在串行链路上的实现指南》
《GB/T 19582.3-2008 第 3 部分: Modbus protocol在 TCP/IP 上的实现指南》
2、Modbus协议概述
Modbus是一个主-从模式的通信协议,属于data链路层上的协议,协议本身不涉及具体的硬件要求。常见的应用Modbus协议的物理接口有RS-485、RS232、USART等的通信链路中。Modbus协议中,一个时刻内只允许有一个主机connect于总线,多个从机connect于总线上,通信都是只能由主机发起,从机进行Response。不能从从机主动发起通信。
3、Modbus 主从机通信模式
主机和从机之间的通信,可以用两种模式进行:广播通知模式、单播点对点模式。
3.1、单播点对点模式
主机按照从机的明确address访问相应的从机,从机接到来自主机的Request并处理完Request后,从机会向主机返回一个应答,Complete一个通信。在这种模式,一个 Modbus 事务处理包含 2 个message:一个来自主机的Request,一个来自从机的应答。在总线上,每个从机都必须有唯一的从机address (1 到 247),这样才能区别于其它节点被独立的寻址。
3.2、广播通知模式
主机向所总线通过广播指令sendRequest,所有的从机都要receive来自主机的广播信息。对于主机广播的Request,从机是没有应答返回的。所有的从机必须要接受主机的广播模写Function。注意:address 0 是专门用于主机向各个从机广播data的。
4、Modbus addressRules
Modbus 寻址空间有 256 个不同address。如下图所示:

address 0 为广播address。所有的从机必须识别广播address。Modbus 主机本身是没有address的,只有从机必须要有一个address。该address必须在 Modbus 串行总线上唯一。248~255作为预留使用的address。
5、Modbus 的帧format
Modbus的帧format按照选择的模式不同帧format也是有所区别的。
5.1、RTU模式
RTU 模式下的帧format如下图:

Modbus RTU 帧总Length最大为 256 byte。RTU 模式每个byte ( 11 位 ) 的format为 :8–位binary,message中每个 8 位byte含有两个 4 位hexadecimal字符(0–9, A–F)每byte的 bit 流:1 start位8 data bit, 首先send最低effective位1 位作为奇even parity1 stop biteven parity是要求的, 其它模式 ( odd parity, 无校验 ) 也可以使用。为了保证与其它产品的最大兼容性, 同时支持无校验模式是建议的。默认校验模式模式 必须为even parity。注 : 使用无校验要求 2 个stop bit。RTU时,每个字符或byte均由此顺序send(从左到右):
最低effective位 (LSB) . . . 最高effective位 (MSB)


5.1.1、RTU模式下的帧通信
由send设备将 Modbus message构造为带有已知start和End标记的帧。这使设备可以在message的开始receive 新帧,并且知道何时messageEnd。不完整的message必须能够被检测到而Error标志必须作为结果被设置。在 RTU 模式,message帧由时长至少为 3.5 个字符time的空闲间隔区分。

整个message帧必须以连续的字符流send。如果两个字符之间的空闲间隔大于 1.5 个字符time,则message帧被认为不完整应该被receive节点丢弃。

注意 :RTU 模式下receivedata时,由于 t1.5 和 t3.5 的time隔要求的existence,一般在高通信速率下,会导致 CPU 负担加重。因此,在通信速率等于或低于 19200 bps 时,这两个定时必须严格遵守;对于Baud rate大于 19200 bps 的情形,应该使用 2 个定时的fixed value:建议的字符间超时time(t1.5)为 750µs,帧间的超时time (t1.5) 为 1.750ms。下图表示了对 RTU 传输模式状态图的描述。”主节点” 和 “子节点” 的不同角度均在相同的图中表示:

上面状态图的一些解释:
1)从 “初始” 态到 “空闲” 态转换需要 t3.5 定时超时: 这保证帧间延迟
2)“空闲” 态是没有send和receivemessage要处理的正常状态。
3)在 RTU 模式, 当没有活动的传输的time间隔达 3.5 个字符长时,通信链路被认为在 “空闲” 态。
4)当链路空闲时, 在链路上检测到的任何传输的字符被识别为帧start。链路变为 “活动” 状态。然后当链路上没有字符传输的time间个达到 t3.5 后,被识别为帧End。
5)检测到帧End后,Complete CRC 计算和检验。然后,分析address域以确定帧是否发往此设备,如果不是, 则丢弃此帧。为了减少receive处理time,address域可以在一接到就分析,而不需要等到整个帧End。这 样,CRC 计算只需要在帧寻址到该节点 (包括广播帧) 时进行。
5.1.2、RTU模式的CRC check
在 RTU 模式包含一个对Allmessage内容执行的,基于循环冗余校验 (CRC – Cyclical Redundancy Checking) 算法的Error检验域。CRC 域检验整个message的内容。不管message有无奇even parity,均执行此检验。CRC 包含由两个 8 位byte组成的一个 16 位值。CRC 域作为message的最后的域附加在message之后。计算后,首先附加低byte,然后是高byte。CRC high字 节为messagesend的最后一个子节。附加在message后面的 CRC 的值由send设备计算。receive设备在receivemessage时重新计算 CRC 的值,并将计 算结果于实际receive到的 CRC 值相比较。如果两个值不相等,则为Error。CRC 的计算, 开始对一个 16 位register预装全 1。然后将message中的连续的 8 位子节对其进行后续的计 算。只有字符中的 8 个data bit参与生成 CRC 的运算,start位,stop bit和check digit不参与 CRC 计算。CRC 的生成过程中, 每个 8–位字符与register中的值异或。然后结果向最低effective位(LSB)方向移动 (Shift) 1 位,而最高effective位(MSB)位置充零。然后提取并检查 LSB:如果 LSB 为 1, 则register中的值与 一个固定的预置值异或;如果 LSB 为 0, 则不进行异或Operation。这个过程将重复直到执行完 8 次移位。Complete最后一次(第 8 次)移位及RelatedOperation后,下一个 8 位byte 与register的current value异或,然后又同上面描述过的一样重复 8 次。当所有message中子节都运算之后得到的寄存 器的最终值,就是 CRC。
5.2、ASCII传输模式
当 Modbus 串行链路equipment被配置为使用 ASCII模式通信时,message中的每个 8 位byte以两个 ASCII 字符send。一般在通信链路或者设备无法 符合 RTU 模式的定时管理时使用该模式。ASCII的帧format如下:

比如 : byte 0X5B 会被Coding为两个字符 : 0x35 和 0x42 ( ASCII Coding 0x35 =”5″, 0x42 =”B” )。注 : 由于一个子节需要两个字符,此模式比 RTU 效率低。
ASCII 模式每个byte ( 10 位 ) 的format为 :hexadecimal,ASCII 字符 0-9, A-F。1 start位7 data bit, 首先send最低effective位1 位作为奇even parity1 stop biteven parity是要求的, 其它模式 ( odd parity, 无校验 ) 也可以使用。为了保证与其它产品的最大兼容性, 同时支持无校验模式是建议的。默认校验模式模式 必须为even parity。注 : 使用无校验要求 2 个stop bit。字符是如何串行传送的:每个字符或byte均由此顺序send(从左到右):
最低effective位 (LSB) . . . 最高effective位 (MSB)


5.2.1、ASCII的message帧
在 ASCII 模式, message用特殊的字符区分帧start和帧End。一个message必须以一个‘冒号’ ( : ) (ASCII hexadecimal 3A )start,以 ‘回车-换行’ (CR LF) 对 (ASCII hexadecimal 0D 和 0A) End。注 : LF 字符可以通过特定的 Modbus 应用命令 (参见 Modbus 应用协议规范) 改变。对于所有的域,允许传送的字符为hexadecimal 0–9, A–F (ASCII Coding)。设备连续的监视总线上的 ‘冒 号’ 字符。当收到这个字符后,每A device解码后续的字符一直到帧End。message中字符间的time间隔可以达一秒。如果有更大的间隔,则接受设备认为发生了Error。特别注意:每个字符子节需要用两个字符Coding。因此,为了确保 ASCII 模式 和 RTU 模式在 Modbus 应 用级兼容,ASCII data域最大dataLength为 (2×252) 是 RTU data域 (252) 的两倍。必然的, Modbus ASCII 帧的最大尺寸为 513 个字符。ASCII message帧的要求在下面的状态图中综合。”主节点” 和 “子节点” 的不同角度均在相同的图中表示:

上面状态图的一些解释:1)“空闲” 态是没有send和receivemessage要处理的正常状态。2)每次receive到 “:” 字符表示新的message的开始。如果在一个message的receive过程中收到该字符,则当前地message 被认为不完整并被丢弃。而一个新的receive缓冲区被重新分配。3)检测到帧End后,Complete LRC 计算和检验。然后,分析address域以确定帧是否发往此设备,如果不是, 则丢弃此帧。为了减少receive处理time,address域可以在一接到就分析,而不需要等到整个帧End。
5.2.2、ASCII的LRC verification
在 ASCII 模式,包含一个对Allmessage内容执行的,基于纵向冗余校验 (LRC – Longitudinal Redundancy Checking) 算法的Error检验域。LRC 域检验不包括start“冒号”和结尾 CRLF 对的整个报 文的内容。不管message有无奇even parity,均执行此检验。LRC 域为一个子节,包含一个 8 位binary值。LRC 值由send设备计算,然后将 LRC 附在message后面。receive设备在receivemessage时重新计算 LRC 的值,并将Computation result于实际receive到的 LRC 值相比较。如果两个值不 相等,则为Error。LRC 的计算, 对message中的所有的连续 8 位byte相加,忽略任何进位,然后求出其binary补码。执行检 验针对不包括start“冒号”和结尾 CRLF 对的整个 ASCII message域的内容。在 ASCII 模式,LRC 的结果 被 ASCII Coding为两个byte并放置于 ASCII 模式message帧的结尾,CRLF 之前。
6、Modbus的Exception Code
MODBUS 事务处理的一般处理过程:

一旦服务器处理Request,使用合适的 MODBUS 服务器事务建立 MODBUS Response。根据处理结果,可以建立两种TypeResponse:
1) 一个正确的 MODBUS Response:Responsefunction code = Requestfunction code
2) 一个 MODBUS Exception Response
3)用来为客户机提供处理过程中与被发现的差错Related的信息;
4)Responsefunction code = Requestfunction code + 0x80;
5)提供一个Exception Code来指示差错原因。
7、Modbus的function code
7.1、function code的类别
目前Modbus的Function中可以分为三类:公共function code、用户定义function code、保留function code。

公共function code :是已经被定义的function code。
用户定义function code :有两个可以由用户定义function code。范围为:65 至 72 和decimal 100 至 110。
保留function code :特殊情况下使用的,并且对公共使用是Invalid的function code。
7.2、公共function code
Modbus中公共function code的定义如下:

7.2.1、线圈Operationfunction code(bit位的Operation)

比如我要读取线圈中的内容。从机address为 11H,线圈register的starting address为 0013H,Endaddress为 0037H。需要查询总共 37 个线圈register,主机send的RTU帧如下:

从机Response的data帧如下:

Parse:线圈 0013H 到线圈 001AH 的状态为 CDH,binary值为 11001101,该byte的最高byte为线圈 001AH , 最 低 字 节 为 线 圈 0013H 。各Coil status与data内容每位相对应。1 代表 ON,0 代表 OFF。线 圈 001AH 到 线 圈 0013H 的 状态分别为:

7.2.2、保持registerOperationfunction code

(1)写多个保持register
写多个保持register使用function code10H。比如:从机address为 11H。保持register的其实address为 0001H,register的Endaddress为 0002H。总共访问 2个register。保持register 0001H 的内容为 000AH,保持register 0002H 的内容为 0102H。
主机Request的RTU帧data如下:


从机返回的Response为:

(2)读保持register
读保持register使用03Hfunction code。比如:从机address为 11H。保持register的starting address为 006BH,Endaddress为 006DH。
主机send的RTURequest帧如下:


从机的应答如下:

发表回复