改程序可以通过修改参数来进行筛选启停设备 同时需要结合设备运行时间及设备状态来进行
//######################################################################################################################################################
//#####################################################################################################################################################
//设备根据运行时间的长短进行启停
//该程序支持多个设备可修改参数来决定
//EBC-LW 20170329 QQ:275578306
(*
程序算法:1.设备状态读入设备状态总表格(结构体)
2.读取设备状态总表格状态将备起和备停设备加入各自的数组表格并排序
3.当存在启动需求时,则调用备起设备第一个表格中的设备编号并启动,若存在问题如故障或跳闸时会更新总表格,则这时表格第一个设备编号即会变化。
4.当存在停止需求时,...
每次来一个启动脉冲即可启动一台设备(低于最多运行数量),每次来一个停止脉冲即可停止一台设备(高于最小运行数量)
*)
//######################################################################################################################################################
//######################################################################################################################################################
FUNCTION_BLOCK FB34
TITLE = 'ATORUN'
//
// 多台设备依据运行时间自动启停程序(可修改常量更改为更多设备)
//
VERSION: '1.0'
AUTHOR: EBC_LW
NAME: ATORUN
FAMILY: EBC
KNOW_HOW_PROTECT
// -------输入------------------------------
VAR_INPUT
RUN_STATUS_DB:BLOCK_DB;//运行状态数据表
(*DB格式如下
ID:INT;//设备编号,程序中不采用仅做为编程方式方便的
SS:DINT;//运行时间(秒)
REMOTE:BOOL;//远程
RUN:BOOL;//运行状态
FAULT:BOOL;//故障状态
TRIP:BOOL;//跳闸状态
AM:BOOL;//手自动状态
*)
NUM:INT:=7;//初始化设备的数量为7台,可外部连接修改值。
ST:BOOL;//启动条件满足,脉冲型
STO:BOOL;//停止条件满足,脉冲型
NUM_H:INT:=5;//设置最多启动台数
NUM_L:INT:=2;//设置最少启动台数
P_WIDE:INT:=5;//脉冲时间长度(秒),用于脉冲指令复位
REST:BOOL;//复位
END_VAR
// -------输出------------------------------
VAR_OUTPUT
END_VAR
// -------输入输出------------------------------
VAR_IN_OUT
END_VAR
// -------常量------------------------------
CONST
NUM_ALL:=10;//10台设备,修改常量编译即扩展需要排序的设备数量
END_CONST
// -------临时------------------------------
VAR_TEMP
PN:BOOL;//秒脉冲上升沿
RUN_ALL_I:DINT;//计算现在运行设备总数的循环体
RUN_ALL_TEMP:DINT;//计算现在运行设备总数的临时变量
ST_FLAG:BOOL;//备起标志位
STO_FLAG:BOOL;//备停标志位
(*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*)
PX_ST_I:INT;//需要启动设备的排序循环体循环变量
PX_STO_I:INT;//需要停止设备的排序循环体循环变量
PX_ST_TEMP1:DINT;//需要启动设备的交换变量1,排序时时间长度的交换的中间变量
PX_ST_TEMP2:DINT;//需要启动设备的交换变量2,排序时设备编号的交换的中间变量
PX_STO_TEMP1:DINT;//需要停止设备的交换变量1,排序时时间长度的交换的中间变量
PX_STO_TEMP2:DINT;//需要停止设备的交换变量2,排序时设备编号的交换的中间变量
(*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*)
CLEAR_TB_I:INT;//清空要排序的启停列表
Initialization_TB_I:INT;//初始化状态表
REST_I:INT;//复位循环体变量
END_VAR
// -------静态变量------------------------------
VAR
OLD_VAL:BOOL;//边沿检测的上一次的值(用于秒脉冲)
RUN_STAUS:ARRAY[1..NUM_ALL]OF STRUCT//设备状态表,该表格即使更新
ID:INT;//设备编号
SS:DINT;//运行时间(秒)
REMOTE:BOOL;//远程信号
RUN:BOOL;//运行状态
FAULT:BOOL;//故障状态
TRIP:BOOL;//跳闸状态
AM:BOOL;//手自动状态
NOT_ST_STO:BOOL;//不能启停
STANDBY_ST:BOOL;//备用启动
STANDBY_STO:BOOL;//备用停止
END_STRUCT;
RUN_ALL:DINT;//设备运行总数
RUN_ALL_OLD:DINT;//上一次设备的运行总数
TB_B_ST:ARRAY[1..2,1..NUM_ALL] OF DINT;//备起排序用的表格
TB_B_ST_I:INT:=0;//备起计数
TB_B_STO:ARRAY[1..2,1..NUM_ALL] OF DINT;//备停排序用的表格
TB_B_STO_I:INT:=0;//备停计数
//控制输出指令
CTL_OUT:ARRAY[1..NUM_ALL] OF STRUCT//控制指令
ID:INT;//设备编号
START_P:BOOL;//启动脉冲,连接外部程序使用,使用地址注意看背景数据块地址
STOP_P:BOOL;//停止脉冲,连接外部程序使用,使用地址注意看背景数据块地址
START:BOOL;//启动指令,连接外部程序使用,使用地址注意看背景数据块地址
END_STRUCT;
CTL_OUT_ST_I:INT;//启动控制输出循环体循环变量
CTL_OUT_STO_I:INT;//停止控制输出循环体循环变量
CTL_OUT_START_I:INT;//单脉冲启停循环体循环变量
ST_P_REST_I:INT:=0;//脉冲复位
STO_P_REST_I:INT:=0;//脉冲复位
ST_P_FLAG:BOOL:=0;//启动设备标志位
STO_P_FLAG:BOOL:=0;//停止设备标志位
ST_COUNT:INT:=0;//启动复位时间计数
STO_COUNT:INT:=0;//停止复位时间计数
ST_PN:BOOL;//启动脉冲,用于启动信号来时只执行一次
ST_OLD:BOOL;//启动脉冲上一次的值
STO_PN:BOOL;//停止脉冲,用于停止信号来时只执行一次
STO_OLD:BOOL;//停止脉冲上一次的值
END_VAR
//#################################脉冲####################################
//使用系统时间存储区产生一个秒脉冲
PN:=M2.5&(NOT OLD_VAL);
OLD_VAL:=M2.5;
//产生一个启动脉冲
ST_PN:=ST&(NOT ST_OLD);
ST_OLD:=ST;
//产生一个停止脉冲
STO_PN:=STO&(NOT STO_OLD);
STO_OLD:=STO;
//########################计算现在运行设备的数量##########################
RUN_ALL_TEMP:=0;
FOR RUN_ALL_I:= 1 TO NUM_ALL BY 1 DO
RUN_ALL_TEMP:=BOOL_TO_DINT(RUN_STAUS[RUN_ALL_I].RUN)+RUN_ALL_TEMP;
END_FOR;
RUN_ALL:=RUN_ALL_TEMP;
//#############################初始化设备状态表格(结构体数组)####################################
//对符合要求数量的计数清零操作
TB_B_ST_I:=0;
TB_B_STO_I:=0;
//清空要排序的列表
FOR CLEAR_TB_I:= 1 TO NUM_ALL BY 1 DO
TB_B_ST[1,CLEAR_TB_I]:=0;
TB_B_ST[2,CLEAR_TB_I]:=0;
TB_B_STO[1,CLEAR_TB_I]:=0;
TB_B_STO[2,CLEAR_TB_I]:=0;
END_FOR;
//设备的总状态表格(结构体数组)有条件进行更新(总运行数量产生变化时或者任意一台设备手自动变化时)
FOR Initialization_TB_I:= 1 TO NUM BY 1 DO
RUN_STAUS[Initialization_TB_I].ID:=WORD_TO_INT(RUN_STATUS_DB.DW[8*(Initialization_TB_I-1)]);
RUN_STAUS[Initialization_TB_I].SS:=DWORD_TO_DINT(RUN_STATUS_DB.DD[8*(Initialization_TB_I-1)+2]);
RUN_STAUS[Initialization_TB_I].REMOTE:=RUN_STATUS_DB.DX[8*(Initialization_TB_I-1)+6,0];
RUN_STAUS[Initialization_TB_I].RUN:=RUN_STATUS_DB.DX[8*(Initialization_TB_I-1)+6,1];
RUN_STAUS[Initialization_TB_I].FAULT:=RUN_STATUS_DB.DX[8*(Initialization_TB_I-1)+6,2];
RUN_STAUS[Initialization_TB_I].TRIP:=RUN_STATUS_DB.DX[8*(Initialization_TB_I-1)+6,3];
RUN_STAUS[Initialization_TB_I].AM:=RUN_STATUS_DB.DX[8*(Initialization_TB_I-1)+6,4];
//不能启动停止的设备:没有在自动状态或者有故障或者有跳闸的均不能启停。
RUN_STAUS[Initialization_TB_I].NOT_ST_STO:=NOT(RUN_STAUS[Initialization_TB_I].AM) OR RUN_STAUS[Initialization_TB_I].FAULT OR RUN_STAUS[Initialization_TB_I].TRIP OR NOT(RUN_STAUS[Initialization_TB_I].REMOTE);
//符合备用启动的条件:设备没有运行且 能启停的状态
RUN_STAUS[Initialization_TB_I].STANDBY_ST:=NOT(RUN_STAUS[Initialization_TB_I].RUN) & NOT(RUN_STAUS[Initialization_TB_I].NOT_ST_STO) ;
//符合备用停止的条件:设备运行且 能启停的状态
RUN_STAUS[Initialization_TB_I].STANDBY_STO:=RUN_STAUS[Initialization_TB_I].RUN & NOT(RUN_STAUS[Initialization_TB_I].NOT_ST_STO);
//将设备编号赋值给控制输出的ID编号
CTL_OUT[Initialization_TB_I].ID:=RUN_STAUS[Initialization_TB_I].ID;
//判断是否符合备用启动条件,符合即将该设备的ID,SS,加入备用启动的列表
IF RUN_STAUS[Initialization_TB_I].STANDBY_ST THEN
//统计符合备用启动要求的台数
TB_B_ST_I:=TB_B_ST_I+1;
//将符合条件的设备加入备启数组
TB_B_ST[1,TB_B_ST_I]:=RUN_STAUS[Initialization_TB_I].ID;//原数据是INT类型存在隐性转换为DINT
TB_B_ST[2,TB_B_ST_I]:=RUN_STAUS[Initialization_TB_I].SS;
END_IF;
//判断是否符合备用停止条件,符合即将该设备的ID,SS,加入备用停止的列表
IF RUN_STAUS[Initialization_TB_I].STANDBY_STO THEN
//统计符合备用停止要求的台数
TB_B_STO_I:=TB_B_STO_I+1;
//将符合条件的设备加入备启数组
TB_B_STO[1,TB_B_STO_I]:=RUN_STAUS[Initialization_TB_I].ID;//原数据是INT类型存在隐性转换为DINT
TB_B_STO[2,TB_B_STO_I]:=RUN_STAUS[Initialization_TB_I].SS;
END_IF;
END_FOR;
//超过上传字数请看第二部分
第二部分地址http://www.ad.siemens.com.cn/club/bbs/post.aspx?a_id=1411597&b_id=4&b_sid=&s_id=23&pno=0