此次讲解以示例项目为例,主要阐述关于SIEMENSS7-1500PLC实现Modbus-RTU通信的配置步骤、程序编写及注意事项,详细的系统配置如下图:

图1:实例系统构成

该实例中,Modbus-RTU主站为安装在S7-1500主机架上的CMPtPRS422/485HF,Modbus-RTU从站模块(站地址为2)为安装在ET200SP分布式IO上的CMPtP,接口类型为RS485,通信波特率为9600bit/s,无奇偶校验。该实例所用的软件及硬件

(一)SIMATIC部件

(二)硬件组态步骤

按照系统配置图,首先组态S7-1516CPU主机架,在主机架上配置点对点通信模块,并将该模块的协议设置为“Modbus”,如下图2:

图2:S7-1500CPU主机架点对点通信模块组态

然后激活CPU的“系统和时钟存贮器功能”,如下图3。(本例程中使用了CPU首次扫描位来实现Modbus的初始化,使用CPU的时钟信号来控制发送频率,该方法供参考。)

图3:激活CPU的系统和时钟存储器

然后组态ET200SP分布式IO站,并在该分布式IO上组态点对点通信模块,并将该模块的通信协议设置为“Modbus”,如下图4:

图4:选择通信协议

ET200SP分布式IO站点对点模块组态,至此硬件配置已完成。

(三)软件编写

S7-1500实现Modbus-RTU功能,需要调用以下指令,见下表3,其中“Modbus_Comm_Load”指令用于通信模块的组态,“Modbus_Master”指令和“Modbus_Slave”指令分别实现Modbus主站通信和Modbus从站通信“Modbus_Comm_Load”指令和“Modbus_Master”/“Modbus_Slave”指令是通过“Modbus_Comm_Load”指令的“MB_DB”参数来实现关联的。

表3.Modbus-RTU相关指令

在此,首先编写Modbus主站程序,添加一个新FB,将其命名为“ModbusMaster”,如下图5:

图5:添加Modbus-Master功能块

在该FB中以多重背景方式调用“Modbus_Comm_Load”指令,该指令在指令目录下“通信—〉通信处理器—〉Modbus(RTU)”下,如下图6:

图6:调用“Modbus_Comm_Load”

在该FB中以多重背景方式调用“Modbus_Master”指令,该指令在指令目录下“通信—〉通信处理器—〉Modbus(RTU)”下,如下图7:

图7:调用“Modbus_Master”指令

表4.Modbus_Comm_Load主要参数列表

首先要为“Modbus_Comm_Load”指令指定端口,即该指令是针对哪个点对点模块进行参数化的。在硬件配置中,每个硬件均有一个硬件标识符,该硬件标识符在硬件属性中可以查看到,如下图8:

图8:在硬件属性中查看模块硬件标识符

同样,该硬件标识符也可以在“PLC变量—〉显示所有变量—〉系统变量”下可以查看到,如下图9:

图9:PLC变量表中查看系统常量

所以可以通过如图10所示方法,通过拖拽的方式,将Modbus主站接口的硬件标识符拖至“Modbus_Comm_Load”指令的“Port”接口参数处,如下图10:

图10:为“Modbus_Comm_Load”指定端口

接下来,定义端口的工作模式,本示例中,点对点模块的工作模式为RS485,所以需要将“Modbus_Comm_Load”背景数据中静态变量的“MODE”参数赋值为4,赋值既可以通过“Move”指令来完成,也可以通过直接修改该静态变量的默认值来实现,本实例使用后一种方法,参见下图11:

图11:定义Modbus-RTU主站端口工作模式为RS485

接下来,通过对“Modbus_Comm_Load”指令的“MD_DB”参数赋值,将“Modbus_Comm_Load”指令与“Modbus_Master”指令进行关联,即将“Modbus_Master”指令的背景DB块中静态变量“MB_DB”赋值给“Modbus_Comm_Load”指令的“MD_DB”,可以通过拖拽的方式来实现,拖拽路径如下图12:

图12

对“Modbus_Comm_Load”指令的“MD_DB”参数赋值除以上操作外,对于“Modbus_Comm_Load”指令的“REQ”参数,本实例使用PLC的首个扫描位来完成。其它参数如波特率,奇偶校验等,请根据实际使用情况对这些参数进行赋值,因本实例波特率为9600bit/s,无奇偶校验,所以以上参数使用缺省设置即可。接下来,对指令“Modbus_Master”进行参数设置,该指令主要参数如下表5所示:

表5.Modbus_Master主要参数列表

表五

由于Modbus指令读取或写入的数据区必须为指针寻址,所以必须是有绝对地址的区域方可访问,而S7-1500创建的DB块缺省为优化的DB块,变量没有绝对地址,无法直接使用。本例中我们创建DB块,并在该DB块内创建一个名为“M_Data”的数组,类型为WORD,长度为100,即创建了100个字的存储空间。然后在该DB块点右键,在属性中将“优化的块访问”前的勾去掉,重新编译该DB块,该DB块就会生成,可以看到每个变量都有偏移地址了,如下图13:

图13:创建一个标准DB块

根据下表6所示的Modbus功能码,本实例需要Modbus主站读取Modbus从站保持寄存器从起始地址开始的10个字的内容到创建的“Master_Data”中,即Modbus功能码03的功能。

表6:Modbus功能码的选择

根据以上要求,则“Modbus_Master”指令应按如下赋值:

“REQ”:本实例使用PLC时钟信号来完成,即下图中的;

“MB_ADDR”:2//访问的从站地址;

“MODE”:0;//与“DATA_ADDR”参数一起决定Modbus功能码为03

“DATA_ADDR”:40001//Modbus地址

“DATA_LEN”:10//数据长度为10个字

“DATA_PTR”:该参数可以通过拖拽的方式,将创建的标准DB内的变量“M_Data”拖拽到“DATA_PTR”处,拖拽路径如下图14:

图14:为“Modbus_Master”指令进行参数赋值

接下来,编写Modbus_RTU从站程序,参照主站的程序,添加一个新FB2“Modbus-Slave”,在该FB中以多重背景方式调用“Modbus_Comm_Load”指令,同样为该指令选择ET200SP的硬件地址,其它通信参数如波特率、奇偶校验等与主站的“Modbus_Comm_Load”指令相同,如下图15:

图15:在从站FB中调用“Modbus_Comm_Load”指令

使用定义主站端口的工作模式相同的方法,将从站点对点模块的工作模式定义为RS485,所以需要将“Modbus_Comm_Load”背景数据中静态变量的“MODE”参数赋值为4,如下图16:

图16:定义Modbus-RTU从站端口工作模式为RS485

然后,以多重背景的方式调用从站指令“Modbus_Slave”指令,并设置Modbus从站地址为2,并为从站创建一个标准的DB块“SlaveData”,长度根据实际情况定,本例中在“SlaveData”中创建了一个长度为200字的数组,并将该变量以拖拽的形式(也可以通过指针P#的方式),将该变量填在“Modbus_Slave”的“MB_HOLD_REG”参数处,如下图17:

图17:调用“Modbus_Slave”指令

然后对“Modbus_Comm_Load”指令的“MD_DB”参数赋值,将“Modbus_Comm_Load”指令与“Modbus_Slave”指令进行关联,即将“Modbus_Slave”指令的背景DB块中静态变量“MB_DB”赋值给“Modbus_Comm_Load”指令的“MD_DB”,可以通过拖拽的方式来实现,拖拽路径如下图18:

图18

将“Modbus_Slave”指令和“Modbus_Comm_Load”指令关联在OB1中分别调用Modbus主站程序块和Modbus从站程序块,并为其分配全局DB块,如下图19:

图19

在OB1中分别调用主站程序和从站程序至此,程序编写基本结束,建立2个变量监视表,分别用来监视Modbus主站数据和Modbus从站数据,将该例程下载到PLC后,可以看到通信模块对应的收发LED指示灯在闪烁,表示端口正在发送/接收数据。将DB块“SlaveData”中的变量赋值,监视主站“MasterData”中的变量,可以看到主站已经读取到从站的数据,如下图20:

图20:使用变量监视表测试

主站侧已成功读取到从站数据Modbus其它功能码使用方法类似,请参照表6修改相应的变量即可,此处不再一一举例。也可以根据此例程,举一反三,编写Modbus-RTU轮询程序。