摘要: 本文介绍了如何通过梯形图读取V6.0版本400H的状态灯,并通过对之前读V4.5版本400H状态灯读取的SCL程序进行解析,介绍如何修改为V6.0版本的代码。
通过系统功能 SFC 51“RDSYSST”(读取系统状态),可以读取CPU或者从站的系统状态列表或部分系统状态列表,参考下面手册:
SIMATIC 用于S7-300/400 系统和标准函数 的系统软件 卷1/2 参考手册
https://support.industry.siemens.com/cs/cn/zh/view/44240604
其中,可以使用SSL-ID = W#16#xy74读取CPU的LED状态

图1-1 SFC 51里相关的帮助
在调用SFC 51时,为了便于分析读到的数据记录,需要在共享DB里声明一个结构体变量SSL_HEADER,再声明足够数量的结构体变量来保存LED状态数据,400H V6版本单个CPU有15个指示灯,冗余控制器有30组,所以案例中声明了30组。

图1-2 在DB块里的变量声明
推荐在扫描周期1秒以上OB调用SFC 51,例如:OB32。在调用 SFC 51 时,通过将值“常1”赋给输入参数REQ 来启动读取,通过赋给不同的状态列表SSL_ID实现不同的功能。在本文档中要读取CPU的所有LED状态,可设置参数SSL_ID=W#16#0074,梯形图的调用如下所示:

图1-3 SFC 51调用
程序执行后,读出的LED灯的状态会放在声明的数组里,在下图中读到了30组数据记录,前边是主CPU的15组,后边是备CPU的15组数据,如下所示:

图1-4 读到的状态灯数据记录
对读到的数据解释如下:
首先N.DR是读到的LED数量,本例中冗余状态灯读到了30组,如果单机运行模式,就只能读到15组。
读到的数据记录顺序和实际CPU上LED灯的顺序并不相同,需要参考手册来判断,每一个指示灯的数据分为3部分:

图1-5 LED指示灯的顺序 如果RACK 1为主CPU,那么第一组数据的LED_ID就为16#F9XX,关于F9的解释参考下面的说明:W#16#F9XX里,F为固定值1111,而9里的Bit 3=1表示主CPU,Bit 0-2为1,表示数据来自于RACK 1且为主CPU的数据。

图1-6 LED指示灯状态值的说明

图1-7 RACK 1 CPU为主时数据记录 通常在画面上根据布尔量显示状态时,需要连接固定的DB地址,所以RACK 1为MASTER时,将数据记录的前后两组数据的进行交换,让RACK 0的数据总在最前面,下图中DB296的变量声明和DB295相同,只是最后多了三个整数,用于BLKMOV的返回值。

图1-8 数据处理第一部分 接下来,当RACK1为主CPU时,通过两次交叉拷贝到新的DB296,将两组数据重新排序,RACK0数据固定在前。

图1-9数据处理第二部分 在将数据按照先RACK0后RACK1排好序后,如果想把所有灯的LED 状态放到一个字里,可以将每一个LED_ON数据里的第1位移到事先声明的BOOL量里,如下所示:

图1-10 将LED_ON状态从BYTE转成BOOL量 同样的方法 ,将BLINK的状态也移到BOOL量里,就可以在WINCC上显示了。 注:经过测试,故障灯的顺序是:
在调用SFC 51时,如果执行过程中报错,可以结合故障代码和手册来分析。
例如在下图中执行出错,返回值为“-32639”。

图1-11 读V6.0 400H 状态灯出错
在变量表里将返回值按16进制显示,得到结果为W#16#8081,在手册或者在线帮助 里,查到故障原因是DR提供的数据区太短,长度为104字节,而V6.0 400H需要120个字节。

图1-12 分析故障原因
前边介绍的梯形图读取400H LED灯状态,受到梯形图的功能限制,对数据的加工处理不大方便。在PCS 7项目里,还要考虑在CPU故障时报警等复杂功能,如果用SCL结构化编程语言,可以大提高编程效率并实现复杂的功能。关于SCL的基础,请参考下面文档:
《S7-SCL编程 》
https://support.industry.siemens.com/cs/cn/zh/view/109481384
接下来对官网的读取V4.5版本400H的SCL例子进行分析,解读它的编程思路和如何修改为适用V6.0版本。通过下面的链接,可以下载到4.5版本的状态灯读取指南和SCL源代码。
《如何读取冗余控制器状态灯》
https://support.industry.siemens.com/cs/cn/zh/view/90318924
关于SCL源文件导入项目,参考:

图2-1 导入SCL源文件
PCS7系统中,使用SCL编辑器来开发在AS控制器中运行的各功能块,必须在格式和内容上遵循一定的标准。下图所示即为一个通用功能块的结构。

图2-2 SCL功能块结构
功能块头中包含了该功能块一些基本的操作信息(我们把它叫做功能块属性Block Attributes)。使用各种不同的功能块属性,我们可以完成各种不同的功能,这些属性将会在功能块的属性对话框中显示。下图所示为各参数实际在功能块中所表征的意义。

图2-3功能块属性
为了能够将需要的变量自动编译到OS,在图2.1 增加了两个属性,其中S7_m_c是“控制和监视”功能,“S7_alarm_ui”是上传消息的属性,如果是PCS 7项目,要设置为1,如果是STEP 7+WINCC,设置为0。
在功能块开始部分要进行变量声明,以配合代码部分的数据处理。
有下列需求时,我们需要定义输入参数:
在下图中的声明里,主要引脚功能如下 :

图2-4 输入变量声明
在上图中,不仅声明了变量,还在大括号里声明了引脚的参数,用于定义该功能块与其他功能块之间或上位机PCS7 OS的接口,也可以通过定义它的系统属性来定制各种特性,常用参数属性见下表:
系统属性 | 相关性 | 注 释 | 类 型 | 默认值 |
|---|---|---|---|---|
S7_sampletime | 时间相关 | 带有该属性的参数将会自动更新为当前循环OB的循环周期 | 功能块相关 | FALSE |
S7_dynamic | CFC | CFC测试模式下的动态显示 | 实例相关 | FALSE |
S7_edit | CFC | CFC中参数/信号分类 | 实例相关 | FALSE |
S7_link | CFC | CFC中是否能被连接 | 功能块相关 | TRUE |
S7_param | CFC | CFC中是否能被参数化 | 功能块相关 | TRUE |
S7_visible | CFC | CFC中是否可见 | 实例相关 | TRUE |
S7_qc | CFC, OCM | 参数是否拥有质量代码 | 功能块相关 | FALSE |
S7_m_c | OCM | 定义该参数是否用于OCM属性 | 功能块相关 | FALSE |
S7_shortcut | OCM | OS面板中显示的模拟量标签名(16个字符Max.) | 实例相关 | NULL |
S7_string_0 | OCM | 输入或输入输出变量参数为"0"时的指示文本(16个字符Max.) | 实例相关 | NULL |
S7_string_1 | OCM | 输入或输入输出变量参数为"1"时的指示文本(16个字符Max.) | 实例相关 | NULL |
S7_server | Server | 消息ID的服务器类型(alarm_archiv) | 功能块相关 | NULL |
S7_a_type | Message Server | 消息ID类型标识 | 功能块相关 | NULL |
表2-1 引脚参数列表
有下列需求时,我们需要定义输入参数:

图2-5 输出变量声明 主要的参数:
与临时变量不同,静态变量会在该功能块前后两次调用过程中传递值(Retained),而且此变量类型在功能块中嵌套调用其他功能块FB时非常有用。如果在该功能块中需要调用其他FB块,则需要在该功能块的静态变量中声明被调用块的多重实例Multiple Instance。静态变量声明示例如下图所示。

图2-6:静态变量声明示例

图2-7:报警抑制相关变量声明
RD_SINFO: SFC 6读取 OB 启动信息,读出是否被OB100调用,如果检测到sbRESTART值为TRUE,那么肯定是被OB100调用,将sbRESTART复位。

图2-8:判断是否OB100调用

图2-9 :对CPU前3次扫描周期结束后ALARM_OUT置位
2.4.2 读取故障灯状态
如果一个功能块需要具有OCM属性,相应的参数能自动上传到OS(监视及控制),则需要设置该功能块及相关参数的监控属性(S7_m_c,仅对FB有效)。本例中需要将灯的状态上传到WINCC并显示,相应参数的OCM属性定义如下图所示

图2-10:OCM属性设置示例
1)读取指灯灯的数据记录
下面是代码里读取故障灯状态的部分。

图2-11 读取LED灯状态
在上面语句里,RDSYSST为SFC51符号名,实际上是调用SFC51,参数为之前声明里初始化的值,读出的数据放到在静态变里声明的数据DR里。
2) 数据粗加工
读到的数据里,前边的数据总是主CPU的,由于并不一定是左侧机架为主CPU,所以要判断前半部分是否属于左侧CPU,如果它属于右侧CPU,那么要对数据记录前后部分交换位置,最后得到排序好的数据,便于在OS上显示。

图2-11 数据处理

图2-12 数据前后交换 接下来, 按照LED灯的排序,判断是否BUSF, IFM1F,REDF等亮起,在V4.5版本,这些灯亮起后,就得到DW#16#001C60E,用它和TEMP 3进行与,如果结果不等于 0,就说明至少有一个故障灯,如果是V6.0版本,这个值应该为DW#16#E3D8712C。

图2-13 故障判断 3) 将排序好的结果赋值
最后把加工的的数据分别赋给LED_ON和LED_BLINK,并且读到 的故障灯顺序号分别赋到LED_ID1 ~ 26。

图2-14 状态值输出
2.4.3 故障时消息上传
如果在功能块中需要产生功能块相关的报警消息,则需要在功能块的静态变量中定义相应报警功能块的多重实例。报警消息的传递、确认以及附属变量的传递等取决于CPU的特性。系统的标准功能库Standard Library中包含了所有能使用的与报警相关的功能块,如下表所示。
在PCS7中使用Alarm_8p功能块触发报警,而且需要设置功能块的报警组态窗口类型为PCS7类型(S7_alarm_ui:=1)。
如果功能块使用了报警相关功能块发送相应报警消息到OS,则首先需要定义一个输入DWORD型参数(例如,EV_ID)。当在CFC中调用该功能块时,此参数会自动从系统中获取唯一的ID。当编译OS时,每条报警的消息ID将自动通过此ID计算得到。因此,需要对该参数的系统属性进行相应的设置。加入系统属性”S7_server:=alarm_archiv”、”S7_a_type:=alarm_8p”(根据使用的报警功能块而定)。同时为了保护该参数不被用户无意中修改,需要设置”S7_visible:=false; S7_link:=false; S7_param:=false”,下图所示为EV_ID声明示例。

图2-15:EV_ID声明示例
在代码最后调用ALARM_8P将CPU_FAILURE CPU_FAULT消息上传,触发信号里均和ALARM_OUT做“与”判断,ALARM_OUT在CPU启动前3个周期为0,以实现前几个周期报警抑制功能。

图2-16 报警处理代码
报警功能块的输入如果没有被使用,可以在用户功能块的接口中定义,以便于用户对相应的功能进行使用。例如,alarm_8p功能块的附属变量即可通过接口的方式提供给用户使用,如下图所示。

图2-17 SCL编译注意事项
首先将文档里的画面文件拷贝到OS项目下的GraCS文件夹。
SCL代码部分编译成FB功能块后,在CFC里调用并编译下载AS和OS,那么在将功能块的变量和消息编译到OS,画面上会自动生成块图标,运行后打开图标可以看到面板。
由于官方文档里的画面是为V4.5版本CPU开发的,在V6.0版本CPU下调用时,需要对面板进行调整,增加原来没有的两个LED,如有必要,还要修改文字显示、颜色和该指示灯在数据记录里的顺序。

图3-1 对画面进行调整