产品描述
西门子淮南PLC模块总代理
在数据报文中,所有的modbus地址都是从0开始的。也就是**出现的数据项在报文中的地址为0。比如:(All data addresses in Modbus messages are referenced to zero. The first occurrence of a data item is addressed as item number zero.)
5)、Modbus地址实际为两种情况。
**种情况:PLC作Modbus主站,Modbus地址和PLC手册里的地址一致,例如作主站的S7-200的MBUS_MSG指令用于向Modbus从站发送请求消息,和处理从站返回的响应消息。要读取从站(另一台S7-200)的I0.0开始的地址区时,它的输入参数Addr(Modbus地址)为10001。S7-200从站保持寄存器的V区起始地址为VB200时,要读取从站VW200开始的V存储区时,保持寄存器的地址是40001。
*二种情况:PLC作从站,PLC不用管什么Modbus地址,等着主站来读写它的地址区就是了。
主站的计算机软件(例如DCS或组态软件)的编程需要编写实现Modbus通信的程序,首先需要确定Modbus RTU的报文结构。他们一般不熟悉PLC,因此PLC的编程人员往往需要和上位机软件的编程一起来讨论Modbus的报文结构。
较容易出问题的就是报文里Modbus地址与PLC存储区地址的对应关系。
S7 PLC手册给出的Modbus与Modicon公司和GE公司PLC使用的地址相同,是基于1的地址,即同类元件的首地址为1。而西门子PLC采用的是基于0的地址,即同类元件的首地址为0。Modbus报文中西门子PLC的Modbus地址也采用基于0的地址。
PLC系统手册中的Modbus地址的较高位用来表示地址区的类型,例如I0.0的Modbus地址为10001。因为地址区类型的信息已经包含在报文的功能码中了,报文中S7-200的I0.0的Modbus地址不是10001,而是0。报文中其他地址区的Modbus地址也应按相同的原则处理。例如当S7-200从站保持寄存器的V区起始地址为VB200时,VW200对应的保持寄存器在报文中的Modbus地址为0,而不是40001。
施耐德plc modbus地址对照表
000001至000XXX是实际输出,对应%QX0.0-%QXX.X
010001至010XXX是实际输入,对应%IX0.0-%IXX.X
030001至030032是模拟量寄存器,对应%AIW0,16位一路依次类推
040001至040XXX是保持寄存器,对应%MX0.0-%MXX.X,1对1,要是%MW就对应16位,依次类推。施耐德PLC中 W表示字 16位,D表示双字 32位。比如:%MW10和%MD10。B表示字节 8位,X表示位。比如:%MB0和%MX0.0~%MX0.7
%MW10.4
%MW10是指一个字,一个字分为2个字节,一个字节8个位,也就是说%MW10中有16个位,从%MW10.0~%MW10.15。
%QW0.5.1.0.10
Q是输出 ,0是机架,5是0号机架的*五个模块,1是*五号模块的**个通道,0是**个通道的*0个字,10是*0个字的*10个位。
Modbus常用功能码学习及实例
一.MODBUS寄存器种类说明虽然MODBUS支持诸多功能码,但其中只涉及到四种寄存器:线圈寄存器、离散输入寄存器、保持寄存器、输入寄存器。
只要搞清楚寄存器的本质和功能码的联系,其实理解功能码就很简单。
寄存器种类 | 读写状态 | 位操作字操作 | 适用功能码 |
---|---|---|---|
线圈寄存器 | 读/写 | 位 | 01H(读); 05H(写单个位); 0FH(写多个位) |
离散输入寄存器 | 只读 | 位 | 02H |
保持寄存器 | 读/写 | 字 | 03H(读); 06H(写单个字节); 0FH(写多个字节) |
输入寄存器 | 只读 | 字 | 04H |
线圈寄存器:可以类比为开关量,每个bit都对应一个信号的开关状态。所以一个字节可以同时控制8路的信号。比如控制外部8路io的高低。 线圈寄存器支持读也支持写,比如控制或者读取电磁阀的开关志状态。对应的功能码有:0x01 0x05 0x0f
离散输入寄存器:离散输入寄存器相当于线圈寄存器的只读模式,每个bit表示一个开关量,而他的开关量只能读取,不能够写入。只能通过外部设定改变输入状态,比如我可以读取外部按键的按下还是松开,但是控制不了按键。对应的功能码有:0x02
保持寄存器:寄存器的单位不再是bit而是两个byte,也就是可以存放具体的数据量的,并且是可读写的。比如我不到那可以读取传感器报警上限下限,也可以设置它的大小。对应的功能码有:0x03 0x06 0x10
输入寄存器:输入寄存器相当于保持寄存器的只读模式,也是只支持读而不能写。一个寄存器也是占据两个字节的空间。比如通过读取输入寄存器获取现在的模拟量采样值。对应的功能码有 0x04
二.MODBUS部分功能码MODBUS支持很多功能码,但是在实际应用的时候常用的也就那么几个。
上面介绍了Modbus的四个寄存器种类:线圈寄存器、离散输入寄存器、保持寄存器、输入寄存器,从寄存器角度理解了对应功能码。下面列出常用功能码,具体如下:
功能码 | 名称 | 数据类型 | 作用 |
---|---|---|---|
0x01 | 读线圈寄存器 | 位 | 取得一组逻辑线圈的当前状态(ON/OFF ) |
0x02 | 读离散输入寄存器 | 位 | 取得一组开关输入的当前状态(ON/OFF ) |
0x03 | 读保持寄存器 | 整型、浮点型、字符型 | 在一个或多个保持寄存器中取得当前的二进制值 |
0x04 | 读输入寄存器 | 整型、浮点型 | 在一个或多个输入寄存器中取得当前的二进制值 |
0x05 | 写单个线圈寄存器 | 位 | 强置一个逻辑线圈的通断状态 |
0x06 | 写单个保持寄存器 | 整型、浮点型、字符型 | 把具体二进值装入一个保持寄存器 |
0x0f | 写多个线圈寄存器 | 位 | 强置一串连续逻辑线圈的通断 |
0x10 | 写多个保持寄存器 | 整型、浮点型、字符型 | 把具体的二进制值装入一串连续的保持寄存器 |
1)功能:读从站线圈寄存器,位操作,可读单个或者多个
2)主机发送指令:
主机发送数据包括:从站地址+功能码+寄存器起始地址+寄存器数量+校验码
假设从站地址为0x01,线圈寄存器开始地址0x0021,结束地址0x002c,即寄存器地址范围为:0x0021~0x0032,总共读取12个连续线圈的状态值,则主机发送指令如下图所示:
从站地址 | 功能码 | 寄存器起始地址高8位 | 寄存器起始地址低8位 | 寄存器数量高8位 | 寄存器数低8位 | CRC校验低8位 | CRC校验高8位 |
---|---|---|---|---|---|---|---|
0x01 | 0x01 | 0x00 | 0x21 | 0x00 | 0x0c | 0xXX | 0xXX |
3)从站响应返回:
从站响应返回数据包括:从站地址+功能码+返回字节数+数据值+校验码
其中,返回数据值的每一位对应线圈状态,线圈状态为ON时,其值为1;状态为OFF时,其值为0;
【数据以小端的形式进行存储,即较低有效位存放于内存较低位地址(位于二进制的右侧)。每8个位组成一个字节,当线圈的数量不是8的倍数时,剩余的位数添0补位。】
从站地址 | 功能码 | 返回字节数 | data1 | data2 | CRC校验低8位 | CRC校验高8位 |
---|---|---|---|---|---|---|
0x01 | 0x01 | 0x02 | 0xCB | 0x0B | 0xXX | 0xXX |
本例中读取12个线圈,12/8商1余4,因此需要2个字节存放应答数据,返回字节数为2。
字节1存放线圈编号21~28的数值(小端字节序,线圈28的值存放在bit7,线圈21的值存放在bit0);
字节2存放线圈编号29~32的数值,剩余位数添0补位;
上表中data1表示0x0021-0x0028的线圈状态,data1的较低位代表较低地址的线圈状态;
data1:0xCB=1100 1011,则data1线圈状态如下表所示:
线圈地址 | 功能码 | 0x28 | 0x27 | 0x26 | 0x25 | 0x24 | 0x23 | 0x22 | 0x21 |
---|---|---|---|---|---|---|---|---|---|
数值 | 0x01 | 1 | 1 | 0 | 0 | 1 | 0 | 1 | 1 |
data2表示地址0x0030-0x0038的线圈状态,不够8位,字节高位填充为0。
data2:0x0B=0000 1011,则data2线圈状态如下表所示:
线圈地址 | 功能码 | 0x30 | 0x2f | 0x2e | 0x2d | 0x2c | 0x2b | 0x2a | 0x29 |
---|---|---|---|---|---|---|---|---|---|
数值 | 0x01 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 1 |
1)功能:读离散输入寄存器,位操作,可读单个或多个,类似功能码0X01,此处省略;
1)功能:读从站保持寄存器,字节操作,可读单个或者多个;每个保持寄存器占2个字节(16位);
2)主机发送指令:
主机发送数据包括:从站地址+功能码+寄存器起始地址+寄存器数量+校验码
假设从站地址为0x03,保持寄存器开始地址为0x003B,结束地址0x003D,即寄存器地址范围为:0x003B~0x003D,总共读取3个保持寄存器的数据,则主机发送指令如下图所示:
从站地址 | 功能码 | 寄存器起始地址高8位 | 寄存器起始地址低8位 | 寄存器数量高8位 | 寄存器数量低8位 | CRC校验低8位 | CRC校验高8位 |
---|---|---|---|---|---|---|---|
0x03 | 0x03 | 0x00 | 0x3B | 0x00 | 0x03 | 0xXX | 0xXX |
3)从站响应返回:
从站响应返回数据包括:从站地址+功能码+返回字节数+数据值+校验码
从站地址 | 功能码 | 返回字节数 | data1H | data1L | data2H | data2L | data3H | data3L | CRC校验低8位 | CRC校验高8位 |
---|---|---|---|---|---|---|---|---|---|---|
0x03 | 0x03 | 0x06 | 0x1B | 0x0B | 0x0A | 0x01 | 0xC2 | 0xDB | 0xXX | 0xXX |
本例中读取3个保持寄存器,每个保持寄存器占2个字节,因此需要6个字节存放应答数据,返回字节数为6。
0x003B~0x003D保持寄存器的数值如下图所示:
寄存器地址 | 0x003D | 0x003C | 0x003A |
---|---|---|---|
数值 | 0xC2 DB | 0x0A 01 | 0x1B 0B |
1)功能:读输入寄存器,字节操作,可读单个或多个,类似功能码0X03,此处省略;
1)功能:对单个线圈进行写操作,位操作,只能写一个。写入0xFF00表示将线圈置为ON,写入0x0000表示将线圈置为OFF,其它值无效;
2)主机发送指令:
主机发送数据包括:从站地址+功能码+寄存器起始地址+数据值+校验码
假设从站地址为0x03,线圈寄存器起始地址为0x0032,要将其设置为ON,则主机发送指令如下表所示:
从站地址 | 功能码 | 寄存器起始地址高8位 | 寄存器起始地址低8位 | dataH | dataL | CRC校验低8位 | CRC校验高8位 |
---|---|---|---|---|---|---|---|
0x03 | 0x05 | 0x00 | 0x32 | 0xff | 0x00 | 0xXX | 0xXX |
3)从站响应返回:
从站应答数据包括:从站地址+功能码+寄存器地址+写入值+校验码
如果数据成功写入,则应答数据与请求数据一样,如下表所示:
从站地址 | 功能码 | 寄存器起始地址高8位 | 寄存器起始地址低8位 | dataH | dataL | CRC校验低8位 | CRC校验高8位 |
---|---|---|---|---|---|---|---|
0x03 | 0x05 | 0x00 | 0x32 | 0xff | 0x00 | 0xXX | 0xXX |
1)功能:对单个保持寄存器进行写操作,字节操作,只能写一个。
2)主机发送指令:
主机发送数据包括:从站地址+功能码+寄存器起始地址+数据值+校验码
假设从站地址为0x01,线圈寄存器起始地址为0x0048,写入数值为0x1234,则主机发送指令如下表所示:
从站地址 | 功能码 | 寄存器起始地址高8位 | 寄存器起始地址低8位 | dataH | dataL | CRC校验低8位 | CRC校验高8位 |
---|---|---|---|---|---|---|---|
0x01 | 0x06 | 0x00 | 0x48 | 0x12 | 0x34 | 0xXX | 0xXX |
3)从站响应返回:
从站应答数据包括:从站地址+功能码+寄存器地址+写入值+校验码
如果数据成功写入,则应答数据与请求数据一样。
产品推荐