西门子S7-1500 PLC可以在其主机架或者分布式IO站安装串口模块来实现点对点通信,硬件模块:CM PtP RS232 HF(6ES7 541-1AD00-0AB0),CM PtP RS422/485 HF(6ES7 541-1AB00-0AB0)和CM PtP(6ES7 137-6AA00-0BA0)。
各模块的具体接线参考模块说明书。
- 打开博图V15.1,创建一个项目:ModbusRTU通讯。
选择CPU 1513-1 PN(6ES7 513-1AL01-0AB0),在主机架上添加CM PtP RS422/485 HF模块,规划为Modbus Master。
在硬件组态的“网络视图”中添加分布式IO站ET 200SP
在分布式IO站上添加CM PtP模块,规划Modbus Slave。
- 配置模块
在主机架的CM PtP RS422/485 HF配置。
全双工(RS422)/半双工(RS485)选择:属性-常规-RS422/485接口-操作模式-指定工作模式。
端口组态:
属性-常规-RS422/485接口-端口组态-协议,选择Modbus协议,并且在“端口参数”设置传输速率、奇偶校验、数据位和结束位。
用同样的方法设置分布式IO站的CM PtP模块。
为了使用CPU的系统存储位和始终存储位,需要在CPU启用这两项功能。
- 编写PLC程序
ModbusRTU通讯要使用的指令包括以下三个:
“Modbus_Comm_Load”指令用于通信模块的组态,“Modbus_Master” 指令和“Modbus_Slave” 指令分别实现 Modbus 主站通信和 Modbus 从站通信。
新建两个数据块MB_Data_Master和MB_Data_Slave,用于Modbus通讯数据的交互存储。该数据块使用指针访问,不能使用“优化的块访问”,新建数据库默认是使用优化的块访问,所以应该在属性里取消“优化的块访问”勾选。
创建FB块MB_Master,使用LAD编程。
编写初始化程序Modbus_Comm_Load,在编程指令-通信-通信处理器-Modbus(RTU),使用多重背景方式调用。
编写初始化程序Modbus_Master,在编程指令-通信-通信处理器-Modbus(RTU),使用多重背景方式调用。
对Modbus_Comm_Load参数进行关联,该指令的主要参数如下:
参数 | 声明 | 数据类型 | 缺省值 | 说明 |
REQ | IN | Bool | FALSE | 当此输入出现上升沿时,启动该指令。 |
PORT | IN | Port | 0 | CM 端口值,即“硬件 ID”(HardwareID) 。符号端口名称在 PLC 变量表的“系统常数”(System constants) 选项卡中指定。 |
BAUD | IN | UDInt | 9600 | 选择数据传输速率有效值为: 300, 600,1200, 2400, 4800,9600,19200, 38400,57600, 76800, 115200bit/s. |
PARITY | IN | UInt | 选择奇偶校验: | |
MB_DB | IN/OUT | MB_BASE | 对 Modbus_Master 或 | |
MODE | Static | USInt | 0 | 工作模式 |
A、首先指定REQ,使用系统存储位“M1.0”,开机启动第一个周期进行初始化操作。
B、指定模块的端口,可以在系统变量中查看。通过拖拽的方式将硬件标识符拖到PORT引脚。
C、定义端口的工作模式,本示例中,点对点模块的工作模式为 RS485,所以需要将“Modbus_Comm_Load”背景数据中静态变量的“MODE”参数赋值为 4,赋值既可以通过“Move”指令来完成,也可以通过直接修改该静态变量的默认值来实现。
D、接下来,通过对“Modbus_Comm_Load”指令的“MD_DB”参数赋值,将“Modbus_Comm_Load”指令与“Modbus_Master”指令进行关联,即将“Modbus_Master”指令的背景 DB 块中静态变量“MB_DB”赋值给“Modbus_Comm_Load”指令的“MD_DB”,可以通过拖拽的方式来实现。
E、其它参数如波特率,奇偶校验等,请根据实际使用情况对这些参数进行赋值,因本实例波特率为 9600bit/s,无奇偶校验,所以以上参数使用缺省设置即可。
对Modbus Master指令参数进行关联,主要参数如下:
参数 | 声明 | 数据类型 | 缺省值 | 说明 |
REQ | IN | Bool | FALSE | FALSE = 无请求 |
MB_ADDR | IN | UInt | 0 | Modbus RTU 站地址: |
MODE | IN | USInt | 0 | 模式选择: 指定请求类型(读取、写入或诊断)。 |
DATA_ADR | IN | UDInt | 0 | 从站中的起始地址: 指定在 |
DATA_LEN | IN | Uint | 0 | 数据长度: 指定此指令将访问的位 |
DATA_PTR | IN/OUT | Variant | 数据指针: 指向要进行数据写入或 |
- 首先指定“REQ”,使用时钟存储位“M0.5”,1Hz时钟脉冲触发通讯,可以根据实际需要对通讯触发周期进行设置。。
- Modbus通讯的功能码,以Modbus功能码03读取保持寄存器为例。
MODE | DATA_ADDR (Modbus 地址) | DATA_LEN | Modbus 功能代码 | 运行和数据 | ||||||
0 | 每个请求的位数: | 01 | 读取输出位: | |||||||
1 | 到 | 9999 | 1 | 到 | 2000/1992(1) | 0 | 到 | 9998 | ||
0 | 每个请求的位数: | 02 | 读取输入位: | |||||||
10001 | 到 | 19999 | 1 | 到 | 2000/1992(1) | 0 | 到 | 9998 | ||
0 | 每个请求的字数: | 03 | 读取保持寄存器: | |||||||
40001 | 到 | 49999 | 1 | 到 | 125/124(1) | 0 | 到 | 9998 | ||
400001 | 到 | 465535 | 1 | 到 | 125/124(1) | 0 | 到 | 65534 | ||
0 | 每个请求的字数: | 04 | 读取输入字: | |||||||
30001 | 到 | 39999 | 1 | 到 | 125/124(1) | 0 | 到 | 9998 | ||
1 | 每个请求的位数: | 05 | 写入一个输出位: | |||||||
1 | 到 | 9999 | 1 | 0 | 到 | 9998 | ||||
1 | 每个请求1个字: | 06 | 写入一个保持寄存器: | |||||||
40001 | 到 | 49999 | 1 | 0 | 到 | 9998 | ||||
400001 | 到 | 465535 | 1 | 0 | 到 | 65534 | ||||
1 | 每个请求的位数: | 15 | 写入多个输出位: | |||||||
1 | 到 | 9999 | 2 | 到 | 1968/1960(1) | 0 | 到 | 9998 | ||
1 | 每个请求的字数: | 16 | 写入多个保持寄存器: | |||||||
40001 | 到 | 49999 | 2 | 到 | 123/122(1) | 0 | 到 | 9998 | ||
400001 | 到 | 465535 | 2 | 到 | 123/122(1) | 0 | 到 | 65534 | ||
2(2) | 每个请求的位数: | 15 | 写入多个输出位: | |||||||
1 | 到 | 9999 | 2 | 到 | 1968/1960(1) | 0 | 到 | 9998 | ||
2(2) | 每个请求的字数: | 16 | 写入多个保持寄存器: | |||||||
40001 | 到 | 49999 | 2 | 到 | 123 | 0 | 到 | 9998 | ||
400001 | 到 | 465535 | 2 | 到 | 122(1) | 0 | 到 | 65534 | ||
11 | 此功能将忽略 Modbus_Master 的 DATA_ADDR 和 DATA_LEN 操作数。 | 11 | 读取从站通信的状态字和事件计数器。状态字表示“忙”(0 - 不忙,0xFFFF - 忙)。事件计数器随着帧的每次成功处理而递增。 | |||||||
80 | 每个请求一个字: | 08 | 使用数据诊断代码 0x0000 检查从站状态(回送测试 - 从站返回请求的回应) | |||||||
— | 1 | — | ||||||||
81 | 每个请求一个字: | 08 | 利用数据诊断代码 0x000A 重新设置从站事件计数器 | |||||||
— | 1 | — | ||||||||
104(3) | 每个请求一个字: | 08 | 读取输入字: | |||||||
0 | 到 | 65535 | 1 | 125/124(1) | 0 | 65535 | ||||
3 到 10, | 保留 | |||||||||
(1) 在扩展寻址中(请参见 Extended_Adressing 参数),最大数据长度根据功能的数据类型而缩减 1 字节或 1 个字。 |
“MB_ADDR”:2 //访问的从站地址;
“MODE”:0;//与“DATA_ADDR”参数一起决定 Modbus 功能码为 03
“DATA_ADDR”:40001 //Modbus 地址
“DATA_LEN”:10 //数据长度为10 个字
“DATA_PTR”:该参数可以通过拖拽的方式,将创建的标准DB 内的变量
然后在组织块里调用FB即可实现Modbus Master功能。
编写Modbus Slave通讯程序。
新建FB块MB_Slave。
和MB_Master一样,在MB_Slave编写初始化程序Modbus_Comm_Load,在编程指令-通信-通信处理器-Modbus(RTU),使用多重背景方式调用。
将“Modbus_Comm_Load”的参数PORT指定为ET200SP的CM PtP的端口,还是用拖拽的方式拖拽过去即可。
将“Modbus_Comm_Load” 背景数据中静态变量的“MODE”参数赋值为4,
在MB_Slave编写初始化程序Modbus_Slave,在编程指令-通信-通信处理器-Modbus(RTU),使用多重背景方式调用。指定Modbus地址MB_ADDR为2,将数据块关联到MB_HOLD_REG ,然后将Mobus_Slave背景数据库的MB_DB关联到Modbus_Comm_Load的MB_DB引脚。
然后在组织块里调用FB即可实现Modbus Slave功能。
- 优化
添加OB83 和OB86 用于故障状态下的响应,为了防止Modbus-RTU 通信模块发生插拔中断或所在的IO 站点发生机架故障时可能引发的通信中断无法恢复,需要在程序中添加OB83 和OB86 并编写相应的程序来对以上2 种情况进行响应和处理。在调用Modbus 主站程序FB 的静态变量下新建一个BOOL 变量“Re_Load_Master”作为标志位,用于在故障恢复时对Modbus 主站模块重新进行参数化,即再次执行“Modbus_Comm_Load”指令。
将刚才创建的变量“Re_Load_Master”添加到主站的“Modbus_Comm_Load”函数块的REQ”触发端,之后再添加一行程序,使用“Modbus_Comm_Load”参数化完成信号“DONE”将该信号复位。
为“Modbus_Master”指令设置调用条件,在“Re_Load_Master”信号没有复位前,禁止执行该指令。
用同样的方法对MB_Slave进行处理。
在PLC 程序块中添加OB83,用于模块发生插拔中断时的故障处理。在OB83 内编写如下程序,第一个程序段用于Modbus RTU 主站模块发生插拔中断后,置位主站重新参数化标志位,用于重新对主站模块进行参数化,并将主站通信指令块“Modbus_Master”背景数据块中的静态变量“MB_State” 清零。
在PLC 程序块中添加OB86,用于模块所属分布式IO 发生机架故障中断时(站故障、站恢复)的处理,在OB86 中编写以下程序,用于Modbus RTU 从站模块所属IO 发生机架故障中断后,置位从站重新参数化标志位,用于重新对从站模块进行参数化,并将从站通信指令块“Modbus_Slave”背景数据块中的2 个静态变量“MB_State” 和“SEND_PTP. y_state”清零。
需要注意的是,由于本例中做Modbus RTU 的主站模块在主机架上,主机架上的模块不会触发OB86,所以在OB86 中并没有Modbus RTU 主站模块相关的程序块;但如果Modbus RTU 的主站模块位于分布式IO 站上,则必须在OB86 中编写相应的程序块对标志位置位、“MB_State” 静态变量清零。
常见问题
- 没有定义端口的工作模式。如未定义,缺省模式为RS232。
- 收发数据区使用了优化的DB。将优化的DB 修改为绝对DB。
- “Modbus_Comm_Load”初始化未执行。重新执行初始化指令。
- “Modbus_Master”指令输入接口参数“DATA_LEN”和“DATA_PTR”不匹配,无法实现收发。“DATA_LEN”必须小于等于“DATA_PTR”指向的数据存储区。
- 点对点通信模块的“TX”/“RX”或“TXD”/“RXD”灯无闪烁。检查“Modbus_Comm_Load”初始化参数,确保其被正确初始化;检查“Modbus_Master”参数和“Modbus_ Slave”指令参数,确保参数正确。
- 点对点通信模块所处的分布式IO 掉站后,又重新连上PLC,但Modbus 通信无法恢复。需要调用OB86,并对“Modbus_Comm_Load”重新进行初始化。
- 点对点通信模块发生插拔模块事件后,即使点对点通信模块被重新插入原来的槽位,但Modbus 通信无法恢复。需要调用OB83,并对“Modbus_Comm_Load”重新进行初始化。
- “TX”/“RX”或“TXD”/“RXD”灯无闪烁。模块没有进入收发数据状态,请检查程序。