Modbus协议详解

Modbus 协议是应用于控制器 上的一种 通用语言。通过此协议,控制器相互之间、控制器经由网络(例如以太网)和其它设备之间可以通信。它已经成为一通用工业标准。有了它,不同厂商生产的控制设备可以连成工业网络,进行集中监控。此协议定义了一个控制器能认识使用的消息结构,而不管它们是经过何种网络进行通信的。它描述了一控制器请求访问其它设备的过程,如果回应来自其它设备的请求,以及怎样侦测错误并记录。它制定了消息域格局和内容的公共格式。当在一个 Modbus 网络上通信时,此协议 决定了 每个控制器须要知道它们的设备地址,识别按地址发来的消息,决定要产生何种行动。如果需要回应,控制器将生成反馈信息并用 Modbus 协议发出。在其它网络上,包含了 Modbus 协议的消息转换为在此网络上使用的帧或包结构。这种转换也扩展了根据具体的网络解决节地址、路由路径及错误检测的方法。协议在一根通讯线上使用 应答式连接(半双工),这意味着在一根单独的通讯线上信号沿着相反的两个方向传输。首先,主计算机的信号寻址到一台唯一的终端设备(从机),然后,在相反的方向上终端设备发出的应答信号传输给主机。

协议只允许在主计算机和终端设备 之间,而不允许 独立的设备之间的数据交换。这就不会在使它们初始化时占据通讯线路,而仅限于响应到达本机的查询信号。

所谓协议不外乎就是通讯格式与通信规范。下面对这俩部分分别介绍:

一、通讯格式

Modbus的通讯协议包括:波特率,检验方式,数据位,停止位

  1. 波特率 一秒钟传送的位数,也就是通讯速率;比如波特率为 9600,即,一秒种可以传送 9600 个位数,
  2. 校验方式 :奇校验或偶校验或无校验,目的是判断传输过程中是否有错误!它只是用于判断一个字符(比如八个位或是七个位组成一个字符)传 输是否有错误。但是它并不能完全能够判断传输是否有错。比如偶校验,在检验送八个11111111”时,如果到达接收方,由于干扰而变成了“10111101”, “1”的个数仍然是偶数,接收方就判断不出来传送的字符已经错误!
  3. 数据位:传输一个字符由几个位组成,计算机的基本单位就是“位”,其值非“0”即“1”,又如传送 A,定义通讯格式时,是定义的八位,其传送 的数据可能就是:00001010
  4. 停止位:传输一个字符有几个停止位,用天判断某个字符是否传输结束,以便开始接收下一个字符。

通讯格式的作用是规范发送方与接收方的传输格式,如果双方通讯格式不一样,接收方就不可能正确判断发送方发来的东西是什么。

比如,接收方设置的波特率是 10(一秒只接收十个位)位,而发送方的波特率是 20(一秒发送二十个位),那么发送方一秒种发送的 20 个字符,接收方就不可能都收到,只能接收到 10 个,造成通讯出错。

校验方式:双方校验方式不一样,就没有一个统一的标准认定传输是否有错误。

数据位,接收方设定的七位,即它接收到七个位就认为是一个字符,而实际发送方设定的是八位,那么接收方认定的字符与发送方发送的字符就不一样了。

二、通讯规范

 通讯格式只是保证接收方正确地接收到发送方传输过来的每一个字符(实际如上所述,检验方式并不能保证完全正确,还要靠通讯规范中的校验和计算来验证整体正确性,下面会继续说明),那么接收到的整串字符做什么用呢,就要靠通讯规范了 MODBUS 的通讯规范很简单 !

1.ASCII 方式:

ASCII 方式发送时的规范定义如下: 起始符 + 设备地址 + 功能代码 + 数据 + 校验 + 结束符

1\ 起始符: 接收到一串字符,总要知道这串字符从哪个地方开始吧,这就是起始符的作用,接收方不管以前收到多少个字符。当接收到起始符时, 以前的字符就不再理它了,从起始符开始分析以后的字符! MODBUS 的 ASCII 方式起始符是一个冒号 “ : “

2\ 设备地址:前面说过,MODBUS 是单主站的主/从通信模式,一个主站下面可以接十多个从站。大家都挂在一条线,如果没有一个设备地址,就不知道是发给哪个 从站的,大家都回应的话,这条线上的信号就乱七八糟了,主站也不知道接收到的是什么了。所以,设这么一个设备地址,告诉是给那个从站的。只要这个从站回答,其他的闭嘴!“二号,请您回答,其他人就不要吱声了。” 广播地址(0)是命令式的,不要求从站回答的。“都听着,晚上全体到我家喝酒去,散会!” 设备地址是要求两个字符,比如发给 2 号站,则是“02” 现在的组合是“:02”

3\ 功能代码: 告诉从站应该做什么,比如读数据的命令是“3”,从站接收到这个命令,再根据下面数据要求的具体地址,把具体地址的数据返回给主站。 功能代码也是要求两个字符,比如读命令 3,则是“03” 现在的组合是“:0203”

4\ 数据:

数据会有不同的情况所以才会有不一样的数据表示,大致分为以下几种:

1、告诉从站具体的元件通讯地址,写入到哪里,从哪里读。如读变频器的设定频率的通讯地址是 00A0 元件的通讯地址要求是 :四个字符,当 控制器的元件地址不足四个字符,则在前面补 0,比如元件通讯地址是 A0,则在前面补足两个 0:“00A0”

2、数据又有可能包括您要读取的字节数( 有的控制器是字数),比如连续读取 PLC 的两个十六位寄存器,其字节数为四个,则是“0004”。读取个数也是要求四个字符,不足四个,前面补零现在的组合是“:020300A00004“

3、而当要实现写入功能时,数据又可能包括写入的数据,比如写入一个十六位寄存器的值,则要包括是写入的数值,如“0D98” 现在的组合是“:020600A00D98“ 06 是单个寄存器的写入命令 Modbus 通信协议

4、当连续写入多个寄存器时,这个数据包括的内容又不一样,它可能是: 寄存器通讯地址 (四个字符) + 字数(四个字符)+ 字节数(两个字符)+ 要写入的数值。起始符 + 设备地址 + 功能代码 + 数据 + 校验 + 结束符 MODBUS 是一种标准通讯协议, 数据呢,因为功能代码的不同,其包含的内容也不同!

5\ 检验和: 

通讯格式里的校验方式并不能保证每个字符都正确,所以这里就把所有字符的值加在一起,其和(检验值)传给接收方,接收再把接收到 的字符的值加在一起,与发送方传送过来的检验值比较,如果相等,就算接收正确了。最大限度的提高传输的可靠性,唯有最大限度地降低干扰!于是产生了 232,485,422 传输方式,他们的区别就在于传输的可靠性! 1+2+3=6 3+2+1=6 这两个字符串的作用肯定是不一样的!但是其校验和是一样的,如果在传输过程中,由于干扰,1 变 3,3 变 1,根据校验和的计算,接收方并不知道由于干扰而造成传输错误,此时,或是出现通讯错误,或是出现通讯混乱。 如,命令码 03,由于干扰而变成了 30,此时校验和是一样的,而 MODBUS 并没有 30 这个命令码,接收不认识,于是出现通讯错误。 再如,读变频器的设定频率通讯地址是 0001,由于干扰而变成了 0010,此时校验和是一样的,但是通讯地址却变了,变频器就可能返回的是其他数据, 造成通讯混乱! 校验字符是要求: 两个字符,如果计算结果超过两个字符,则取后两位! 参加校验计算的字符是 起始符与校验符之间的字符串(不含起始符与校验符) 现在的组合是“:02030A000004FB“ (假设校验和为 FB) 02030A000004 参加校验和计算。

这里简单提及一下关于S232与S485的区别:

http://www.elecfans.com/emb/jiekou/20180418663969.html(详细可以查看网址)

RS232是全双工的,但是485为半双工。

RS485与RS232仅仅是通讯的物理协议(即接口标准)有区别,RS485是差分传输方式(发送端在两条信号线上传输幅值相等相位相反的电信号,接收端对接受的两条线信号作减法运算,这样获得幅值翻倍的信号。其抗干扰的原理是:假如两条信号线都受到了同样(同相、等幅)的干扰信号,由于接受端对接受的两条线的信号作减法运算,因此干扰信号被基本抵消)RS232是单端传输方式,但通讯程序没有太多的差别。

 6\ 结束符: 

接收到一串字符,总要知道在那个地方结束吧,这就是结束符的作用,接收方不管以后还会收到多少个字符。当接收到结束符时,以后再接收的字符就 算是下一轮的东西了,从起始符到结束符之间的字符就是它要分析的字符! MODBUS 的 ASCII 方式结束符是‐‐‐ Chr$(13) + Chr$(10) 现在的组合是“:02030A000004FB“+ Chr$(13) + Chr$(10) 至此,ASCII 方式的发送就完成了,控制器接收到此串字符后,根据 MODBUS 协议定义的通讯规范分析此串字符的作用,然后返回相应的字符! 注意:发送的字符都是以十六进制数表示!

2.RTU 方式:

RTU方式发送时的规范定义如下: 至少 3.5 个字符传输时间的停顿间隔时间标定消息的开始

设备地址 + 功能代码+ 数据 + 校验 + 至少 3.5 个字符传输时间的停顿间隔时间标定了消息的结束其他的就不用说了,与 ASCII 方式一样的作用,比如通讯格式是 9600,E,8,1 比如一秒传送 9600 个位, 通讯格式已经标定了一个字符为7 个位或 8个位,那 3.5 个字符的传送时间就好算了吧: 3.5*11(或 10)=39 个位(35 个位), 传 3.5 个字符需要的时间是:39/9600=4 毫秒。这里虽然显示是8位但是还有一个起始位,奇或偶的校验位(无奇偶校验,则没有此位),停止位(两个停止位就是 2 了。) 就是说,您得保证发送字符串的连续性,中间停顿时间超过 4 毫秒,接收方就认为您已经发送完了这组消息,开始处理了。这就是至少 3.5 个字符传输时 间的停顿间隔时间标定了消息的结束的含义 如果发送的太连续,下一组消息与上一组消息之间的间隔时间没超过 4 毫秒,接收方就认为这些字符是一组消息,按一组消息去处理。所以,发送结束一组命令后,必须间隔 4 毫秒才能发送下一组命令。

 

三、通讯信息

这里的通讯信息是指主机发送的信息与从机发送的信息,我们经常使用的就是读取信息的通信过程:这里是常用的功能码:

 

 

 

在我们读取信息的时候分为读取保持寄存器(holding)与读取输入寄存器(input),这里说一下保持寄存器与输入寄存器的区别:modbus协议最开始是用来解决PLC的通信协议问题的,主要用于输入输出数字量信号以及模拟量信号,所谓的输入寄存器就是从模拟量信号输入引申出来的,即输入寄存器只能从模拟量信号输入端改变寄存器,而主机则不能通过下发指令改变输入寄存器的数据,而保持寄存器则是用于输出模拟量信号的,主机是可以改变寄存器数据。这里是官方话语,其实简单的说就是对于主机而言,保持寄存器是可读可写的,但是输入寄存器是只可读不可以写入,但是对于从机而言,俩者区别不大。

 

 

 

 

 

 

 

这里举个例子:在使用我们modbus poll 模拟主机时,从机会发出:

0104140000000c000000000000000000000000000000005082

这里的01表示从机号,04表示功能码读取,14表示总共上发多少个字节,这里0000代表从机第一个寄存器的数据,这里是因为每一个寄存器分别对应2个字节,第一个是高位数据第二个是低位数据,即前俩个00表示高位数据,后俩位00表示低位数据(具体数据存放不清楚的可以查看寄存器存放数据的问题),介于我们查询了10个寄存器故0000000c00000000000000000000000000000000分别对应这10个寄存器的,5082这里对应的就是他的CRC检验。

这里我们说一下CRC校验,在检验和的时候我们提过数据可能会出现错误数据传输。Modbus使用的是CRC16校验 x16+x15+x2+1 16进制表示为8005

1 预置一个 16 位寄存器为 0FFFFH(全 1),称之为 CRC 寄存器。

2 把数据帧中的第一个 8 位字节与 CRC 寄存器中的低字节进行异或运算,结果存回 CRC 寄存器。

3 CRC 寄存器向右移一位,最高位填以 0,最低位移出并检测。

4 如果最低位为 0:重复第 3 步(下一次移位)。

如果最低位为 1:将 CRC 寄存器与一个预设的固定值(0A001H)进行异或运算。

5 重复第 3 步和第 4 步直到 8 次移位。这样处理完了一个完整的八位。

6 重复第 2 步到第 5 步来处理下一个八位,直到所有的字节处理结束。

因为使用的cRC16的检验,这里的错码率为1/65536。

 

四、出错情况

这里会有一个出错情况的分析,这里大致分为以下几种情况:

  1. 从机接收查询,通讯错误正常处理信息,则返回一个正常响应事件。
  2. 由于通讯出错,从机不能接收查询数据,因而不返回响应。此时,主机依靠处理程序给出查询超时事件。

3.若从机接收查询,发现有  CRC通讯错误,并返回响应,此时,依靠主机处理程序给出查询超时事件。

4.从机接收查询,无通讯错误,但无法处理(如读不存在的线圈和寄存器)时,向主机报告错误的性质。

当从机发生不正常响应时,在正常通讯的情况下会返回数据告诉主机这里发生了问题,与正常数据相比,不正常响应信息有 2 个与正常响应不相同的区域:

功能代码区:正常响应时,从机的响应功能代码区,带原查询的功能代码。所有功能代码的 MSB 为 0(其值低于 80H)。不正常响应时,从机把功能代码的 MSB 置为 1,使功能代码值大于 80H,高于正常响应的值。简单的说,我们返回正常的功能码的数值是在01-72的范围,但是返回的数据为73~119的时候就代表此时功能代码出现问题,主机应用程序能识别不正常响应事件,能检查不正常代码的数据区

数据区:正常响应中,数据区含有(按查询要求给出的) 数据或统计值,在不正常响应中,数据区为一个不正常代码,它说明从机产生不正常响应的条件和原因.

 

上述图中的Exception Code就是指从机发送给主机的异常代码,下表为其异常代码表:

    

 

 

posted @ 2021-03-01 09:28  陈晓猛  阅读(4415)  评论(0编辑  收藏  举报