如何用S7-200 Smart PLC实现 FB 块编程
2021-11-25路则明
路则明
(济南中正金码科技有限公司,山东济南 250101)
1. Smart PLC 提供的程序框架[1]
Smart PLC提供的程序构架包含:主程序、子例程和中断程序。
因为SBR子例程在形式上类似FB块,为了实现FB块编程,我们需要从SBR找到突破口。为此,我们研究一下子例程所对应的变量表。下面是某个子例程的变量表:
变量类型为IN的变量共6个:
Act、Feedback、Button_reset、Time_100ms、Pointer和SN。它们对应的数据类型分别为BOOL、BOOL、BOOL、INT、DWORD、DWORD。
变量类型为IN_OUT的变量共1个:
Alarm,其数据类型为BOOL。
变量类型为TEMP的变量共5个:
Time_count、Act_previous、SN_32x、Clock_strobe和Act_latched,它们的数据类型均为DWORD。
可以看出,变量类型有IN、OUT、IN_OUT和TEMP类型。其中,TEMP是临时变量。我们知道,PLC是扫描执行的,当PLC再次扫描执行到该SBR时,上次调用中计算得到的存在于TEMP变量中的结果将全部丢失,这就给我们用FB块编程带来了困难。
2.中型PLC如何实现FB块编程[2]
2.1 S7-1500 PLC通过Static型即静态变量实现FB块编程
1500是西门子的中型PLC,与smart的变量表相比,其FB块中的变量类型多了最关键的一种:静态变量Static。此种变量的特点:FB在每次扫描周期的调用过程开始,其值能够保持为上次调用过程中计算的结果。
DB中的Static型变量,保证了运算结果的正确性。
2.2 Q系列PLC通过自动分配的全局变量提供FB块运行所需要的资源
三菱Q系列PLC,则是预先在“自动分配软元件设置”界面设定好需要的寄存器等资源。编程中调用FB块时,GX WORKS2软件自动给该FB块分配所需的软元件即全局变量,无须人工指定。
3. Smart PLC用全局变量指针实现FB块编程[3]
3.1 用Smart 实现FB块 编程的先天性困难
该PLC不支持背景数据块,也不支持由系统自动分配FB块所需要的全局变量资源。
3.2 Smart 实现FB块 编程的方法
首先,我们以SBR为依托,把程序语句编写在SBR内,而SBR的某个IN型形参则由全局变量指针赋值。在SBR中,我们用传入的全局变量指针开辟出一块全局数据区,SBR内程序的运行所需要的变量资源由此全局数据区、IN型、IN_OUT型、OUT型变量组成。
下面我们通过一个例子看具体实现:
在图1中,“Function_报警”就是一个FB块,它对应的变量表如前述第1节所示。
图1 FB块调用
假如有3个气缸,每个气缸在末端都安装有磁性开关,程序中需要通过磁开的状态来确定气缸是否运动到位,若没有运动到位则报警。用上述FB块来实现本功能,在主程序中可以按图1形式来调用。其中:
Act:气缸伸出时的Q输出点;
Feedback:伸出到位磁开对应的I输入点;
Time_100ms:报警时间预设值。若气缸从伸出开始直到伸出到位用时2000ms,则此值可设定为22,因本FB块内部的时基是100ms,表示经过22×100=2200ms后,还没检测到Feedback对应的磁开则报警。
Alarm:报警标志位。
Button_reset:复位按钮,用于复位该报警。
下面分析其余的2个IN型变量Pointer和SN及5个TEMP型变量Time_count、Act_previous、SN_32x、Clock_strobe和Act_latched在程序中的使用,首先看下面程序段(1):
(1)LD Always_On
MOVD #SN, #SN_32x
*D +32, #SN_32x
MOVD #SN_32x, #Time_count
+D #Pointer, #Time_count
MOVD +2, #Act_previous
+D #Time_count, #Act_previous
MOVD +3, #Clock_strobe
+D #Time_count, #Clock_strobe
MOVD +4, #Act_latched
+D #Time_count, #Act_latched
其中,Pointer为 &VB100,即寄存器VB100的指针。SN为1,表示调用本FB块所需要的序号。可求出其余TMEP型变量所对应的指针,例如,经过乘法运算*D后,SN_32x的值为32;经过第一个加法运算+D语句后,Time_count的值则为&VB132;以此类推,Act_previous的值为&VB134;Clock_strobe的值为 &VB135;Act_latched的值为&VB136。
程序段(1)的作用:本程序段用于初始化临时变量即TEMP型变量,为TEMP型变量分配指向PLC全局变量的指针。这就保证了主程序中每次扫描执行该FB块的调用程序时,FB块中临时变量的值并不是随机的,而是上次扫描执行所计算的结果。
下面的程序段(2)是Time_count的使用:
(2) LDB= *#Act_latched, 1
A 时钟_100ms
LPS
AB= *#Clock_strobe, 0
AB= *#Act_previous, 1
+I 1, *#Time_count
LPP
MOVB 1, *#Clock_strobe
其中,“时钟_100ms”是定时器T33,它和定时器T34构成周期为100ms的方波。当Act_latched的值为1时,通过加法指令+I,Time_count存储的是气缸开始动作后以100ms为时基的计数器值。
可以看出,如果没有前述(1)中的初始化,Time_count不指向全局变量的话,我们就无法得到正确的计数器值。
3.3 主程序中多次调用FB块的实现
在程序段(1)中,*D语句的功能实际上是通过 SN*32来计算出相应FB块用的全局变量的指针偏移。假如我们还要在主程序中调用“Function_报警”FB块两次,而Pointer为 &VB100保持不变,则在调用它们时,SN分别赋值为2和3,那么对应的FB块中的Time_count的值则为 &VB166和&VB198。也就是说,每次调用,用PLC中不同块区的全局寄存器VB作为相应FB块的资源,保证了多次调用的运行结果正确。
4.结语
在SBR子例程的入口参数中,增加两个IN型形参Pointer和SN,调用时把全局寄存器VBxxx的地址指针即&VBxxx传递给Pointer,并用不同的SN作为块调用的序列号,就能实现类似中型PLC所具有FB块编程的功能。