下面是S7-1200的SCL语言6台电机控制功能块的代码:
```
FUNCTION_BLOCK MotorControl
TITLE = \'Motor Control\'
VERSION : INT := 1; // 版本号
StartTime : INT := 10; // 启动延时时间
StopTime : INT := 10; // 停止延时时间
FaultTime : INT := 5; // 故障延时时间
LevelPV : REAL := 0.0; // 液位计数值
ContNum : INT := 6; // 受控电机数量
ContLevel1 : REAL := 0.0; // 自控液位值1
ContLevel2 : REAL := 0.0; // 自控液位值2
ContLevel3 : REAL := 0.0; // 自控液位值3
ContLevel4 : REAL := 0.0; // 自控液位值4
ContLevel5 : REAL := 0.0; // 自控液位值5
ContLevel6 : REAL := 0.0; // 自控液位值6
FBReset : BOOL := FALSE; // 功能块复位开关
StandbyNum : INT := 0; // 参与自控电机总数量
RunningNum : INT := 0; // 正在运行中的电机数量
// 单个电机的输入输出接口
VAR_INPUT
Auto : BOOL; // 自动控制标志,1表示参与自控,0表示不参与自控
Run : BOOL; // 运行信号,1表示正在运行,0表示未运行
Fault : BOOL; // 故障信号,1表示故障,0表示正常
END_VAR
VAR_OUTPUT
Start : BOOL; // 启动信号,1表示启动,0表示停止
END_VAR
// 单个电机的内部变量
VAR
StartTimeLeft : INT := 0; // 启动延时剩余时间
StopTimeLeft : INT := 0; // 停止延时剩余时间
FaultTimeLeft : INT := 0; // 故障延时剩余时间
AutoRunTime : REAL := 0.0; // 自动模式下的运行时间
END_VAR
// 所有电机的内部变量
VAR
Motor1 : MotorType; // 电机1
Motor2 : MotorType; // 电机2
Motor3 : MotorType; // 电机3
Motor4 : MotorType; // 电机4
Motor5 : MotorType; // 电机5
Motor6 : MotorType; // 电机6
END_VAR
// 电机类型定义
TYPE MotorType :
STRUCT
Auto : BOOL; // 自动控制标志,1表示参与自控,0表示不参与自控
Run : BOOL; // 运行信号,1表示正在运行,0表示未运行
Fault : BOOL; // 故障信号,1表示故障,0表示正常
StartTimeLeft : INT := 0; // 启动延时剩余时间
StopTimeLeft : INT := 0; // 停止延时剩余时间
FaultTimeLeft : INT := 0; // 故障延时剩余时间
AutoRunTime : REAL := 0.0; // 自动模式下的运行时间
END_STRUCT
END_TYPE
// 冒泡排序法,由短到长排列一个数组
FUNCTION BubbleSort(
Arr : ARRAY [1..ContNum] OF REAL
) : ARRAY [1..ContNum] OF REAL
VAR
i, j : INT;
tmp : REAL;
BEGIN
FOR i := 1 TO ContNum - 1 DO
FOR j := 1 TO ContNum - i DO
IF Arr[j] > Arr[j+1] THEN
tmp := Arr[j];
Arr[j] := Arr[j+1];
Arr[j+1] := tmp;
END_IF;
END_FOR;
END_FOR;
RETURN Arr;
END_FUNCTION
// 计算满足参与自控条件的电机数量
StandbyNum := 0;
IF Motor1.Auto AND NOT Motor1.Fault THEN
StandbyNum := StandbyNum + 1;
END_IF;
IF Motor2.Auto AND NOT Motor2.Fault THEN
StandbyNum := StandbyNum + 1;
END_IF;
IF Motor3.Auto AND NOT Motor3.Fault THEN
StandbyNum := StandbyNum + 1;
END_IF;
IF Motor4.Auto AND NOT Motor4.Fault THEN
StandbyNum := StandbyNum + 1;
END_IF;
IF Motor5.Auto AND NOT Motor5.Fault THEN
StandbyNum := StandbyNum + 1;
END_IF;
IF Motor6.Auto AND NOT Motor6.Fault THEN
StandbyNum := StandbyNum + 1;
END_IF;
// 计算正在运行中的电机数量
RunningNum := 0;
IF Motor1.Run THEN
RunningNum := RunningNum + 1;
END_IF;
IF Motor2.Run THEN
RunningNum := RunningNum + 1;
END_IF;
IF Motor3.Run THEN
RunningNum := RunningNum + 1;
END_IF;
IF Motor4.Run THEN
RunningNum := RunningNum + 1;
END_IF;
IF Motor5.Run THEN
RunningNum := RunningNum + 1;
END_IF;
IF Motor6.Run THEN
RunningNum := RunningNum + 1;
END_IF;
// 复位功能块内所有变量
IF FBReset AND
(NOT Motor1.Auto OR Motor1.Fault) AND
(NOT Motor2.Auto OR Motor2.Fault) AND
(NOT Motor3.Auto OR Motor3.Fault) AND
(NOT Motor4.Auto OR Motor4.Fault) AND
(NOT Motor5.Auto OR Motor5.Fault) AND
(NOT Motor6.Auto OR Motor6.Fault) THEN
// 复位版本号和延时时间
VERSION := 1;
StartTime := 10;
StopTime := 10;
FaultTime := 5;
// 复位液位计数值和受控电机数量
LevelPV := 0.0;
ContNum := 6;
// 复位自控液位值
ContLevel1 := 0.0;
ContLevel2 := 0.0;
ContLevel3 := 0.0;
ContLevel4 := 0.0;
ContLevel5 := 0.0;
ContLevel6 := 0.0;
// 复位所有电机的数据
Motor1.Auto := FALSE;
Motor1.Run := FALSE;
Motor1.Fault := FALSE;
Motor1.StartTimeLeft := 0;
Motor1.StopTimeLeft := 0;
Motor1.FaultTimeLeft := 0;
Motor1.AutoRunTime := 0.0;
Motor2.Auto := FALSE;
Motor2.Run := FALSE;
Motor2.Fault := FALSE;
Motor2.StartTimeLeft := 0;
Motor2.StopTimeLeft := 0;
Motor2.FaultTimeLeft := 0;
Motor2.AutoRunTime := 0.0;
Motor3.Auto := FALSE;
Motor3.Run := FALSE;
Motor3.Fault := FALSE;
Motor3.StartTimeLeft := 0;
Motor3.StopTimeLeft := 0;
Motor3.FaultTimeLeft := 0;
Motor3.AutoRunTime := 0.0;
Motor4.Auto := FALSE;
Motor4.Run := FALSE;
Motor4.Fault := FALSE;
Motor4.StartTimeLeft := 0;
Motor4.StopTimeLeft := 0;
Motor4.FaultTimeLeft := 0;
Motor4.AutoRunTime := 0.0;
Motor5.Auto := FALSE;
Motor5.Run := FALSE;
Motor5.Fault := FALSE;
Motor5.StartTimeLeft := 0;
Motor5.StopTimeLeft := 0;
Motor5.FaultTimeLeft := 0;
Motor5.AutoRunTime := 0.0;
Motor6.Auto := FALSE;
Motor6.Run := FALSE;
Motor6.Fault := FALSE;
Motor6.StartTimeLeft := 0;
Motor6.StopTimeLeft := 0;
Motor6.FaultTimeLeft := 0;
Motor6.AutoRunTime := 0.0;
END_IF;
// 对自控液位值数组进行排序
ContLevelArr : ARRAY [1..ContNum] OF REAL := [ ContLevel1, ContLevel2, ContLevel3, ContLevel4, ContLevel5, ContLevel6 ];
BubbleSort(ContLevelArr);
ContLevel1Sorted := ContLevelArr[1];
ContLevel2Sorted := ContLevelArr[2];
ContLevel3Sorted := ContLevelArr[3];
ContLevel4Sorted := ContLevelArr[4];
ContLevel5Sorted := ContLevelArr[5];
ContLevel6Sorted := ContLevelArr[6];
// 处理电机1
IF Motor1.Auto AND NOT Motor1.Fault THEN
IF LevelPV >= ContLevel1Sorted THEN
// 启动延时结束,启动电机1
IF Motor1.StartTimeLeft <= 0 THEN
Motor1.Run := TRUE;
Motor1.AutoRunTime := Motor1.AutoRunTime + 1.0; // 记录自动模式下的运行时间
ELSE
Motor1.StartTimeLeft := Motor1.StartTimeLeft - 1;
END_IF;
ELSE
// 停止延时结束,停止电机1
IF Motor1.Run AND (Motor1.StopTimeLeft <= 0) THEN
Motor1.Run := FALSE;
Motor1.AutoRunTime := 0.0; // 清零自动模式下的运行时间
ELSE
Motor1.StopTimeLeft := Motor1.StopTimeLeft - 1;
END_IF;
END_IF;
// 故障延时结束后,切换至其它满足参与自控条件的电机
IF Motor1.Fault AND (Motor1.FaultTimeLeft <= 0) THEN
IF Motor2.Auto AND NOT Motor2.Fault THEN
Motor2.Run := TRUE;
Motor1.Run := FALSE;
ELSEIF Motor3.Auto AND NOT Motor3.Fault THEN
Motor3.Run := TRUE;
Motor1.Run := FALSE;
ELSEIF Motor4.Auto AND NOT Motor4.Fault THEN
Motor4.Run := TRUE;
Motor1.Run := FALSE;
ELSEIF Motor5.Auto AND NOT Motor5.Fault THEN
Motor5.Run := TRUE;
Motor1.Run := FALSE;
ELSEIF Motor6.Auto AND NOT Motor6.Fault THEN
Motor6.Run := TRUE;
Motor1.Run := FALSE;
ELSE
Motor1.Run := FALSE;
END_IF;
ELSE
Motor1.FaultTimeLeft := Motor1.FaultTimeLeft - 1;
END_IF;
// 发送启动信号
IF Motor1.Run THEN
Start := TRUE;
ELSE
Start := FALSE;
END_IF;
ELSE
// 不参与自控或故障状态下,停止电机1
Motor1.Run := FALSE;
Motor1.AutoRunTime := 0.0; // 清零自动模式下的运行时间
Motor1.StartTimeLeft := 0;
Motor1.StopTimeLeft := 0;
Motor1.FaultTimeLeft := 0;
Motor1.Fault := FALSE;
Start := FALSE;
END_IF;
// 处理电机2
IF Motor2.Auto AND NOT Motor2.Fault THEN
IF LevelPV >= ContLevel2Sorted THEN
// 启动延时结束,启动电机2
IF Motor2.StartTimeLeft <= 0 THEN
Motor2.Run := TRUE;
Motor2.AutoRunTime := Motor2.AutoRunTime + 1.0; // 记录自动模式下的运行时间
ELSE
Motor2.Start |