顺着这个页面:http://www.hollysys.cn/templates/lxwm/index.aspx?nodeid=22,打电话咨询一下?!
N80和PPC系列可编程控制器
MODBUS通讯协议
(Ver1.3)
深圳市矩形科技有限公司
地址:深圳市宝安72区留仙三路甲岸工业园A2栋3楼
邮编:518054
电话:0755-27440377,27440378
传真:0755-27440851-8016
网址:http://www.plcstar.com
目 录
1.1 REMOTE TERMINAL UNIT (RTU)
2.1 读取线圈状态(功能码01)-READ OUTPUT 0XXXX STATUS
2.2 读保持型寄存器(功能码03) READ OUTPUT 4XXXX REGISTER
2.3 写单一线圈(功能码05)FORCE SINGLE COIL 0XXX
2.4 写一个寄存器(功能码06)-PRESET SINGLE REGISTER 4XXXX
2.5 写多个线圈(功能码15)-FORCE MULTIPLE COILS 0XXXX
2.6 写多个寄存器(功能码16)PRESET MULTIPLE REGISTERS 4XXXX
该协议定义了ModBus总线MASTER(主站)与SLAVE(从站)之间的通讯报文格式,对于主站来说,MODBUS协议是联系PLC的接口,而且所有的通讯都是“透明的”。
MODBUS协议是工业最常用的PLC通信协议 包含RTU及ASC II两种格式,两种格式的报文各字段解释是相同的。他们之最大的差别他们执行错误核对的方式与字符的格式。目前V80和PPC11支持RTU格式。
在RTU模式下存在帧同步时间。(以表示一个帧的起始和结束),接收站监视连续2个字符之间的时间间隔,如发现总线空闲超过4个半字符时间则认为一个帧已结束,同时认为下一个字符为下一帧的帧地址。在V80和PPC11的软件中,可以在PLC设置功能下设置这个时间的长短,使其可以适应各种不同设备的需求。
空闲时间 | 地址 | 功能码 | 数据 | CRC校验 | 空闲时间 |
T1T2T3 | ADDRESS | FUNCTION | DATA | CHECK | T1T2T3 |
8-BITS | 8-BITS | N*8-BITS | 2*8-BITS |
图1-2 RTU报文帧格式
MODBUS协议的站地址可由8-BITS (RTU)或2个字符所组成,这些位指示出那个从站(使用者寻址)应去接收由主站所传送来的报文。
每个从站必须指定一个唯一的站地址,而唯有报文地址与该从站的地址相同时,该从站才会响应主站的通信。当从站送出应答报文后,从站的地址告诉主站是那一个从站正在通讯中。
广播报文的地址是零。所有的从站都将接收此报文的指令,但接收到报文的从站都不会应答主站。
主站在通信中不需要站地址。
功能码指示被寻址到的从站应该作什么动作
功能码的高位如果从站装置设定为某值,以告诉主站,一个不正常的响应正在传送给它,
如果从站应答的功能码与主站下传的功能码一致.则表示所传送的是一个正常的应答或响应的报文。下表列出MODBUS的功能码。
表1-1功能码
___ ___
码 意义
02 读输入接点(READ INPUT STATUS)
03 读保持型寄存器(READ HOLDING REGISTER)
04 读输入型寄存器(READ INPUT REGISTER)
05 写单线圈(FORCE SINGLE COIL)
06 写单寄存器(PRESET SINGLE REGISTER)
15 写多线圈(FORCE MULTIPLE COILS)
16 写多寄存器(PRESET MULTIPLE REGISTERS)
数据区包含从站欲执行特定功能时所需要的信息或者包含从站被询问后所应答给主站的信息。这些信息包含地址偏移、长度、数据。例如:从从站读取寄存器的功能码,去读的寄存器的基地址及读多少个数据。
校验码可让主站或从站去检查传输过程中是否有错误发生,有时候因为噪声或其它的干扰会使传送或接收中的数据出错,而校验可以使主站或从站不对错误的报文作动作,所以校验可以增加MODBUS系统的安全性及效率。
在校验码中,对于RTU 模式使用CRC-16校验码。MODBUS的CRC16格式在网络上有很多现成的算法,大家可以下载到VB、VC、C的很多有用的源程序,主要的实现方式有异或运算或者是查表方式。
如果询问或响应的报文用中文表示的话,则报文中的4个字段就会如下图所示。
(NOTE:传送的顺序是——站地址功能码 数据区 校验码)
MODBUS的询问/应答报文的内容
资料 | 功能码 | ||
整个帧的校验码 | 数据及扩展命令 | 命令 | 对从站 N 的询问 |
SLAVE 从站 MASTER 主站
地址 | 功能码 | 资料 | 校验 |
从从站 N | 重复主站的命令 | 应答的数据 | 整个帧的校验 |
通信帧的功能码会指出MODBUS上的那一块特定的数据区域会被寻址到,例如功能码1 ,5及15会指向线圈COIL (0XXXX),功能码2指向输入接点(1XXXX),功能3, 6及16参考到保持型寄存器(HOLDING REGISTER) (4XXXX),功能码4指向输入接点(3XXXX)。
所有的偏移地址都是以相对于零来做参考点,例如COIL 00127在通信帧中以0126来寻址(0126 decimal)=007E(hex),在MODBUS的格式里所有的数字都是以十六进制的方式来表示的。
在本节中所举的例子都将以RTU模式为例,读者可以利用以下的方法来编写自己的协议来与PLC通信或联网。
下示的例子是“读保持型寄存器” 40108~40110 (M-BUS 从站的站地址是01),报文分别以RTU或ASC II模式来表示,将会如下图所显示:
主站发送:
报 文 RTU(bit)
帧头 无
站地址 0000 0001 01 1号从站
功能码 0000 0011 03 读保持型寄存器(4XXXX)
寄存器起始地址:
高字节 0000 0000 00
低字节 0110 1011 6B 40108(6BH=108-1)
读寄存器的数目:
高字节 0000 0000 00
低字节 0000 0011 03 读3个
校验码:
高字节 0111 0100 74
低字节 0001 0111 17
帧尾 无
共8字节
从站应答:
报 文 RTU(bit)
帧头 无
站地址 0000 0001 01 1号从站
功能码 0000 0011 03 读保持型寄存器(4XXXX)
数据长度: 0000 0110 06 6个字节
数据 高字节 0000 0010 00
数据 低字节 0110 1011 63 数据1
数据 高字节 0000 0010 00
数据 低字节 0110 1011 63 数据2
数据 高字节 0000 0000 00
数据 低字节 0110 0011 63 数据3
CRC校验 高字节 0101 0101 55
CRC校验 低字节 0100 1010 4A 校验
帧尾 无
共11字节
1.询问
此功能让主站可以从从站中读取线圈的(LOGIC COIL)开/关的状态, 广播模式并不支持该功能码。每次询问最多可以读取到1024个线圈,不过,有许多的从站会根据系统的性能要求,而限制在此最大量以下。
特别注意的一点就是线圈的起始号码与实际的对应,因为PLC的线圈是从1起始的,而ModBus通信协议中定义的线圈是从0开始的,因此PLC的0001线圈对应的是ModBus中的0000,依此类推 图1-2-1是此功能的例子,读取的是1号从站上的COIL 00020到00056的状态:
ADDR | FUNC | DATA START PT HI | DATA START PT LO | DATA #OF PTS HI | DATA #OF PTS LO | CRC16 CHECK | |
站地址 | 功能码 | 数据起始地址高字节 | 数据起始地址低字节 | 数据偏移高字节 | 数据偏移低字节 | 校验码 | |
01 | 01 | 00 | 13 | 00 | 25 | 0C | 14 |
图1-2-1 读输出线圈状态询问报文
2.响应
在图5~3显示的就是从站对询问所作的响应报文,每个位表示一个线圈。响应的报文包含有从站的站地址 功能码 资料字符的数目 资料字符及校验码,COIL的位如果是1的话就代表是ON,对于那些COIL的数目未达到8的倍数的部分,在高位的尾端便填零。
比方说读取的是从0002开始地址的3个位,而0001~0016的数值为0101 0110,则上传 的数据为0000 0011。
线圈的排列顺序如下图所示:
COIL 20到27的状态是CD (HEX)=1100,1101(BINARY),此表示COIL的次序是从右到左,其对应如下
27 th COIL
ADDR | FUNC | BYTE COUNT | DATA COIL STATUS 20-27 | DATA COIL STATUS 28-35 | DATA COIL STATUS 36-43 | DATA COIL STATUS 44-51 | DATA COIL STATUS 52-56 | CRC16 CHECK | |
站地址 | 功能码 | 数据字节数 | 数据00020 ~00027 | 数据00028 ~00035 | 数据00036 ~00043 | 数据00044 ~00051 | 数据00052 ~00056 | 校验码 | |
01 | 01 | 05 | CD | 6B | B2 | 0E | 1B | 44 | EA |
图1-2-2 读输出状态响应报文
从上图可知COIL 27,26,23,22及20都是ON的状态,而52到59这8位当中的最左三位(不需要的这三个位)都被设为零。
1.询问:
此功能允许主站寻址从站中的保持型寄存器(HOLDING REGISTER)的16进制内容 这些寄存器可用来储存有关的定时器或计数器的数值。每次询问可以寻址最大125个寄存器,这些寄存器从零开始算起,40001=ZERO,40002=ONE,....)
广播模式在此功能是不允许的。
以下的例子是从第1号从站中读取从40108到40110的寄存器的内容。
ADDR | FUNC | DATA START REG HI | DATA START REG LO | DATA #OF REGS HI | DATA #OF REGS LO | CRC16 CHECK | |
站地址 | 功能码 | 数据起始地址高字节 | 数据起始地址低字节 | 数据偏移高字节 | 数据偏移低字节 | 校验码 | |
01 | 03 | 00 | 6B | 00 | 03 | 74 | 17 |
图1-2-3 读输出寄存器询问报文
2.响应
被寻址到的从站所响应的报文包括功能码及地址及数据长度,数据长度包含2个字节以描述从站应答的数据字节长度。
在下列中显出40108到40110的缓存器各拥有555,0及100的十进制值。
ADDR | FUNC | BYTE COUNT | DATA OUTPUT REG HI 40108 | DATA OUTPUT REG LO 40108 | DATA OUTPUT REG HI 40109 | DATA OUTPUT REG LO 40109 | DATA OUTPUT REG HI 40110 | DATA OUTPUT REG LO 40110 | CRC16 CHECK | |
站地址 | 功能码 | 数据字节数 | 数据40108高字节 | 数据40108低字节 | 数据40109高字节 | 数据40109低字节 | 数据40110高字节 | 数据40110低字节 | 校验码 | |
01 | 03 | 06 | 02 | 2B | 00 | 00 | 00 | 64 | 05 | 7A |
图1-2-4 读输出寄存器响应报文
1.询问:
此功能可写单一线圈的开或关。在控制器内的任何线圈都能够被强制成ON或OFF的状态。因为控制器是主动地在扫描,如果同一线圈PLC与主站都进行写,则双方都可以进行控制。
线圈的号数也是从零算起(COIL 0001=0,COIL 0002=1....),
如果下置的数据为是【FF】【00】表示闭合【00】【00】表示断开,其他数值非法,所以也不会影响到COIL的状态。
当站地址被定为零(广播模式),则会使所有的从站去会对同一COIL进行修改。
下面的例子是使从站 1的COIL 00173变成ON的状态。
ADDR | FUNC | DATA COIL # HI | DATA COIL # LO | DATA ON OFF | DATA ON OFF | CRC16 CHECK | |
站地址 | 功能码 | 线圈偏移地址高字节 | 线圈偏移地址低字节 | 下置的数据高8位 | 下置的数据低8位 | 校验码 | |
01 | 05 | 00 | AC | FF | 00 | 4C | 1B |
图1-2-5 写单一线圈询问报文
写COIL成功后重传接收到的报文。
ADDR | FUNC | DATA COIL # HI | DATA COIL # LO | DATA ON OFF | DATA ON OFF | CRC16 CHECK | |
站地址 | 功能码 | 线圈偏移地址高字节 | 线圈偏移地址低字节 | 下置的数据高8位 | 下置的数据低8位 | 校验码 | |
01 | 05 | 00 | AC | FF | 00 | 4C | 1B |
图1-2-6 写单一线圈应答报文
1.询问:
此功能码允许使用者去更改一个保持型寄存器的内容,在控制器内的任何一个寄存器都能够应用这个报文来更改它的内容,虽然如此,因为控制器是主动扫描的,所以保持型寄存器不光被主站驱动,也有可能被PLC驱动,这需要用户自行回避多驱动的问题。这些值可以二进制的方式表示,其最大可达到控制器的最大容量,而不用的高字节位(HIGH ORDER BITS)必须设定成零。
ADDR | FUNC | DATA REG #40136 HI | DATA REG #40136 LO | DATA VALUE HI | DATA VALUE LO | CRC16 CHECK | |
站地址 | 功能码 | 寄存器地址高字节 | 寄存器地址低字节 | 写数据的高字节 | 写数据的低字节 | 校验码 | |
01 | 06 | 00 | 87 | 03 | 9E | B8 | BB |
图1-2-7设定寄存器询问报文
2.响应:
写寄存器成功后,从站重传接收到的报文。
ADDR | FUNC | DATA REG 40136 HI | DATA REG 40136 LO | DATA VALUE | DATA VALUE | CRC16 CHECK | |
站地址 | 功能码 | 寄存器地址高字节 | 寄存器地址低字节 | 写数据的高字节 | 写数据的低字节 | 校验码 | |
01 | 06 | 00 | 87 | 03 | 9E | B8 | BB |
图1-2-8设定寄存器应答报文
1.询问:
此报文写多个线圈的状态在控制器内的线圈都能够被强制成ON或OFF的状态,由于控制器一直主动地在扫描,所以除非COIL被强制,否则控制器也能够更改线圈的状态。
写的多个线圈的值包含在数据中,每一个位代表一个COIL的ON或OFF,0代表OFF,1代表ON。
下例中,从开始地址20(13HEX)起,有10个线圈被强制状态,数据域的CD=1100,1101和00=0000,0000表线圈27,26,23,22和20都被强制成ON的状态。
ADDR | FUNC | HI ADDR | LO ADDR | QUANTITY | BYTE CNT | DATA COIL STUS 20-27 | DATA COIL STUS 28-29 | CRC16 CHECK | ||
站地址 | 功能码 | 线圈偏移高字节 | 线圈偏移低字节 | 线圈数高字节 | 线圈数低字节 | 字节数 | 线圈状态20-27 | 线圈状态28-29 | 校验码高字节 | 校验码低字节 |
01 | 0F | 00 | 13 | 00 | 0A | 02 | CD | 00 | B3 | 0B |
图1-2-9写多线圈询问报文
2.响应:
正常的响应是从站站地址、功能码、起始地址及所写的COIL数目的回送 。
ADDR | FUNC | HI ADDR | LO ADDR | QUANTITY | CRC16 CHECK | ||
站地址 | 功能码 | 线圈偏移高字节 | 线圈偏移低字节 | 线圈数高字节 | 线圈数低字节 | 校验码高字节 | 校验码低字节 |
01 | 0F | 00 | 13 | 00 | 0A | 24 | 09 |
图1-2-10写多线圈应答报文
1.询问:
任何的保持型寄存器(在控制器之内)都能够用这个报文来改变它的内容,但是控制器也能够同时更改它的保持型寄存器的内容,所以用户要自行回避多驱动的问题,最后不用的高位必须设定为零。
在广播模式中,所有的从控制器都将会把特定的内容加载到所指定的缓存器。
ADDR | FUNC | HI ADDR | LO ADDR | QUANTITY | BYTE CNT | HI DATA | LO DATA | HI DATA | LO DATA | CRC16 CHECK | ||
站地址 | 功能码 | 寄存器偏移高字节 | 寄存器偏移低字节 | 寄存器数 | 字节数 | 数据高字节 | 数据低字节 | 数据高字节 | 数据低字节 | 校验码高字节 | 校验码低字节 | |
01 | 10 | 00 | 87 | 00 | 02 | 04 | 00 | 0A | 01 | 02 | 1A | 7A |
图1-2-11设定多缓存器询问报文
2.响应:
从站的应答是回传站地址、功能码、起始地址及所要写的寄存器的数据长度。
ADDR | FUNC | HI ADDR | LO ADDR | QUANTITY | CRC16 CHECK | ||
站地址 | 功能码 | 寄存器偏移高字节 | 寄存器偏移低字节 | 寄存器数高字节 | 寄存器数低字节 | 校验码高字节 | 校验码低字节 |
01 | 10 | 00 | 87 | 00 | 02 | F1 | E1 |
图1-2-12设定多缓存器响应报文