Поправил скрипт, поправил неточности в библиотеке

This commit is contained in:
2026-07-31 11:20:45 +03:00
parent d3da512178
commit 3d52fdec57
44 changed files with 1956 additions and 51 deletions
+34
View File
@@ -0,0 +1,34 @@
(*
===============================================================================
Project : PLC_Library
Device : -
Path : Общие
Name : ALARM_1
Type : FUNCTION_BLOCK
Exported : 2026-07-31 11:16:16
===============================================================================
*)
FUNCTION_BLOCK ALARM_1
(* Функциональный блок проверяет входное значение X на принадлежность [LO_1HI_1]*)
VAR_INPUT
X : REAL; (* Контролируемое значение. *)
LO_1 : REAL; (* Нижний предел 1. *)
HI_1 : REAL; (* Верхний предел 1. *)
HYS : REAL; (* Значение гистерезиса (берется как HYS/2 отностительно середины) *)
END_VAR
VAR_OUTPUT
Q1_LO : BOOL := FALSE; (* Флаг «значение меньше нижнего предела 1». *)
Q1_HI : BOOL := FALSE; (* Флаг «значение больше верхнего предела 1». *)
END_VAR
VAR
tmp: REAL;
END_VAR
(*----- IMPLEMENTATION -----*)
tmp := X - HYS * 0.5;
IF tmp > LO_1 THEN Q1_LO := FALSE; END_IF;
IF tmp > HI_1 THEN Q1_HI := TRUE; END_IF;
tmp := tmp + HYS;
IF tmp < LO_1 THEN Q1_LO := TRUE; END_IF;
IF tmp < HI_1 THEN Q1_HI := FALSE; END_IF;
END_FUNCTION_BLOCK
+42
View File
@@ -0,0 +1,42 @@
(*
===============================================================================
Project : PLC_Library
Device : -
Path : Общие
Name : ALARM_2
Type : FUNCTION_BLOCK
Exported : 2026-07-31 11:16:16
===============================================================================
*)
FUNCTION_BLOCK ALARM_2
(* Функциональный блок проверяет входное значение X на принадлежность [LO_1HI_1] [LO_2HI_2] *)
VAR_INPUT
X : REAL; (* Контролируемое значение. *)
LO_1 : REAL; (* Нижний предел 1. *)
HI_1 : REAL; (* Верхний предел 1. *)
LO_2 : REAL; (* Нижний предел 2. *)
HI_2 : REAL; (* Верхний предел 2. *)
HYS : REAL; (* Значение гистерезиса (берется как HYS/2 отностительно середины) *)
END_VAR
VAR_OUTPUT
Q1_LO : BOOL := FALSE; (* Флаг «значение меньше нижнего предела 1». *)
Q1_HI : BOOL := FALSE; (* Флаг «значение больше верхнего предела 1». *)
Q2_LO : BOOL := FALSE; (* Флаг «значение меньше нижнего предела 2». *)
Q2_HI : BOOL := FALSE; (* Флаг «значение больше верхнего предела 2». *)
END_VAR
VAR
tmp: REAL;
END_VAR
(*----- IMPLEMENTATION -----*)
tmp := X - HYS * 0.5;
IF tmp > LO_1 THEN Q1_LO := FALSE; END_IF;
IF tmp > LO_2 THEN Q2_LO := FALSE; END_IF;
IF tmp > HI_1 THEN Q1_HI := TRUE; END_IF;
IF tmp > HI_2 THEN Q2_HI := TRUE; END_IF;
tmp := tmp + HYS;
IF tmp < LO_1 THEN Q1_LO := TRUE; END_IF;
IF tmp < LO_2 THEN Q2_LO := TRUE; END_IF;
IF tmp < HI_1 THEN Q1_HI := FALSE; END_IF;
IF tmp < HI_2 THEN Q2_HI := FALSE; END_IF;
END_FUNCTION_BLOCK
+50
View File
@@ -0,0 +1,50 @@
(*
===============================================================================
Project : PLC_Library
Device : -
Path : Общие
Name : ALARM_3
Type : FUNCTION_BLOCK
Exported : 2026-07-31 11:16:16
===============================================================================
*)
FUNCTION_BLOCK ALARM_3
(* Функциональный блок проверяет входное значение X на принадлежность [LO_1HI_1] [LO_2HI_2] [LO_3HI_3] *)
VAR_INPUT
X : REAL; (* Контролируемое значение. *)
LO_1 : REAL; (* Нижний предел 1. *)
HI_1 : REAL; (* Верхний предел 1. *)
LO_2 : REAL; (* Нижний предел 2. *)
HI_2 : REAL; (* Верхний предел 2. *)
LO_3 : REAL; (* Нижний предел 3. *)
HI_3 : REAL; (* Верхний предел 3. *)
HYS : REAL; (* Значение гистерезиса (берется как HYS/2 отностительно середины) *)
END_VAR
VAR_OUTPUT
Q1_LO : BOOL := FALSE; (* Флаг «значение меньше нижнего предела 1». *)
Q1_HI : BOOL := FALSE; (* Флаг «значение больше верхнего предела 1». *)
Q2_LO : BOOL := FALSE; (* Флаг «значение меньше нижнего предела 2». *)
Q2_HI : BOOL := FALSE; (* Флаг «значение больше верхнего предела 2». *)
Q3_LO : BOOL := FALSE; (* Флаг «значение меньше нижнего предела 3». *)
Q3_HI : BOOL := FALSE; (* Флаг «значение больше верхнего предела 3». *)
END_VAR
VAR
tmp: REAL;
END_VAR
(*----- IMPLEMENTATION -----*)
tmp := X - HYS * 0.5;
IF tmp > LO_1 THEN Q1_LO := FALSE; END_IF;
IF tmp > LO_2 THEN Q2_LO := FALSE; END_IF;
IF tmp > LO_3 THEN Q3_LO := FALSE; END_IF;
IF tmp > HI_1 THEN Q1_HI := TRUE; END_IF;
IF tmp > HI_2 THEN Q2_HI := TRUE; END_IF;
IF tmp > HI_3 THEN Q3_HI := TRUE; END_IF;
tmp := tmp + HYS;
IF tmp < LO_1 THEN Q1_LO := TRUE; END_IF;
IF tmp < LO_2 THEN Q2_LO := TRUE; END_IF;
IF tmp < LO_3 THEN Q3_LO := TRUE; END_IF;
IF tmp < HI_1 THEN Q1_HI := FALSE; END_IF;
IF tmp < HI_2 THEN Q2_HI := FALSE; END_IF;
IF tmp < HI_3 THEN Q3_HI := FALSE; END_IF;
END_FUNCTION_BLOCK
+36
View File
@@ -0,0 +1,36 @@
(*
===============================================================================
Project : PLC_Library
Device : -
Path : Общие
Name : BLINK_LMP
Type : FUNCTION_BLOCK
Exported : 2026-07-31 11:16:16
===============================================================================
*)
FUNCTION_BLOCK BLINK_LMP
(*
Мигание лампами в завистмости от статуса
*)
VAR_INPUT
State: WORD:=0; (* 0 - выключено; 1 - включено; 2 - мигание с частотой 1; 3 - мигание с частотой 2; 4 - мигание с частотой 3; *)
Inp_BL_1: BOOL := FALSE; (* Пульсар миганич с частотой 1 *)
Inp_BL_2: BOOL := FALSE; (* Пульсар миганич с частотой 2 *)
Inp_BL_3: BOOL := FALSE; (* Пульсар миганич с частотой 3 *)
END_VAR
VAR_OUTPUT
LMP: BOOL;
END_VAR
VAR
END_VAR
(*----- IMPLEMENTATION -----*)
CASE State OF
0: LMP:=FALSE;
1: LMP:=TRUE;
2: LMP:=Inp_BL_1;
3: LMP:=Inp_BL_2;
4: LMP:=Inp_BL_3;
END_CASE;
END_FUNCTION_BLOCK
+72
View File
@@ -0,0 +1,72 @@
(*
===============================================================================
Project : PLC_Library
Device : -
Path : Общие
Name : BUZZER_CTRL
Type : FUNCTION_BLOCK
Exported : 2026-07-31 11:16:16
===============================================================================
*)
FUNCTION_BLOCK BUZZER_CTRL
(*
Звучание звонком лампами в завистмости от статуса с возможностью отключения звука
*)
VAR_INPUT
State: WORD:=0; (* 0 - выключено; 1 - включено; 2 - мигание с частотой 1; 3 - мигание с частотой 2; 4 - мигание с частотой 3; *)
Sound_off: BOOL; (* Отключение звука *)
Inp_BL_1: BOOL := FALSE; (* Пульсар миганич с частотой 1 *)
Inp_BL_2: BOOL := FALSE; (* Пульсар миганич с частотой 2 *)
Inp_BL_3: BOOL := FALSE; (* Пульсар миганич с частотой 3 *)
PermanentOFF_Enable: BOOL := FALSE; (*Включение возможности отключить звук перманентно *)
T_PermanentOFF: TIME := T#10S; (* Время удержания кнопки отключения звука для перманентного отключения *)
END_VAR
VAR_OUTPUT
BUZZER: BOOL;
END_VAR
VAR
R_TRIG_0: R_TRIG;
R_TRIG_1: R_TRIG;
R_TRIG_2: R_TRIG;
R_TRIG_3: R_TRIG;
R_TRIG_4: R_TRIG;
B_ctrl: WORD;
T_S_OFF: TON;
R_TRIG_S_OFF: R_TRIG;
AlltimeOff: BOOL;
TP1: TP:=(PT:=T#100MS);
R_TRIG1: R_TRIG;
F_TRIG1: F_TRIG;
F_TRIG2: F_TRIG;
END_VAR
(*----- IMPLEMENTATION -----*)
R_TRIG_0(CLK:=(State=0)); IF R_TRIG_0.Q THEN B_ctrl:=0; END_IF;
R_TRIG_1(CLK:=(State=1)); IF R_TRIG_1.Q THEN B_ctrl:=1; END_IF;
R_TRIG_2(CLK:=(State=2)); IF R_TRIG_2.Q THEN B_ctrl:=2; END_IF;
R_TRIG_3(CLK:=(State=3)); IF R_TRIG_3.Q THEN B_ctrl:=3; END_IF;
R_TRIG_4(CLK:=(State=4)); IF R_TRIG_4.Q THEN B_ctrl:=4; END_IF;
T_S_OFF(IN:=Sound_off, PT:=T_PermanentOFF);
R_TRIG_S_OFF(CLK:=Sound_off AND PermanentOFF_Enable);
R_TRIG1(CLK:=AlltimeOff);
F_TRIG1(CLK:=AlltimeOff);
TP1(IN:=R_TRIG1.Q OR F_TRIG1.Q);
F_TRIG2(CLK:=TP1.Q);
IF R_TRIG_S_OFF.Q THEN B_ctrl:=0; AlltimeOff:=0; END_IF
IF T_S_OFF.Q THEN AlltimeOff:=1; END_IF
IF AlltimeOff THEN B_ctrl:=0; END_IF;
IF TP1.Q THEN B_ctrl:=1; END_IF;
IF (F_TRIG2.Q OR F_TRIG1.Q) THEN B_ctrl:=0; END_IF;
CASE B_ctrl OF
0: BUZZER:=FALSE;
1: BUZZER:=TRUE;
2: BUZZER:=Inp_BL_1;
3: BUZZER:=Inp_BL_2;
4: BUZZER:=Inp_BL_3;
END_CASE;
END_FUNCTION_BLOCK
@@ -0,0 +1,59 @@
(*
===============================================================================
Project : PLC_Library
Device : -
Path : Общие
Name : Button_acceleration
Type : FUNCTION_BLOCK
Exported : 2026-07-31 11:16:16
===============================================================================
*)
FUNCTION_BLOCK Button_acceleration
(* Ускорение изменения значения при нажатой кнопке *)
VAR_INPUT
Button: BOOL;
D_0: REAL := 0; (* Прирост при одиночном нажатии *)
T_W_1: TIME := T#0s; (* Время кратковременного удержания *)
T_D_1: TIME := T#200ms; (* Шаг времени прироста при кратковременном удержании *)
D_1: REAL := 0; (* Прирост при кратковременном удержании *)
T_W_2: TIME := T#0S; (* Время длительного удержания *)
T_D_2: TIME := T#200MS; (* Шаг времени прироста при длительном удержании *)
D_2: REAL := 0; (* Прирост при длительном удержании *)
Zeroes : BOOL := false; (* При этом флаге происходит сброс в 0 при дадании -D_0 << D_0 *)
END_VAR
VAR_IN_OUT
Out: REAL; (* Вход-выход который изменяется *)
END_VAR
VAR
Ton_1: TON;
Ton_2: TON;
TOF_1: TOF;
TOF_2: TOF;
R_TRIG_0: R_TRIG;
R_TRIG_1: R_TRIG;
R_TRIG_2: R_TRIG;
END_VAR
VAR_OUTPUT
END_VAR
(*----- IMPLEMENTATION -----*)
Ton_1(PT := T_W_1,IN:=Button);
Ton_2(PT := T_W_2,IN:=Button);
TOF_1(PT := T_D_1,IN:=Ton_1.Q AND NOT(TOF_1.Q) AND NOT(Ton_2.Q));
TOF_2(PT := T_D_2,IN:=Ton_2.Q AND NOT(TOF_2.Q));
R_TRIG_0(CLK:=Button AND NOT(Ton_1.Q) AND NOT(Ton_2.Q));
R_TRIG_1(CLK:=TOF_1.Q);
R_TRIG_2(CLK:=TOF_2.Q);
IF R_TRIG_0.Q THEN
Out:=Out+D_0;
END_IF
IF R_TRIG_1.Q THEN
Out:=Out+D_1;
END_IF
IF R_TRIG_2.Q THEN
Out:=Out+D_2;
END_IF
IF Zeroes AND ABS(Out) < ABS(D_0) THEN
Out:=0;
END_IF
END_FUNCTION_BLOCK
+46
View File
@@ -0,0 +1,46 @@
(*
===============================================================================
Project : PLC_Library
Device : -
Path : Общие
Name : CONFIRMATION
Type : FUNCTION_BLOCK
Exported : 2026-07-31 11:16:16
===============================================================================
*)
FUNCTION_BLOCK CONFIRMATION
(*
Квитирование
*)
VAR_INPUT
Alarm: BOOL; // Авария
ControlState_On: BOOL; // Управление с текущего поста
Sound_Off: BOOL; // Сигнал снятия звука
Confirmation: BOOL; // Сигнал квитирования
END_VAR
VAR_OUTPUT
Lamp_Alarm_C: WORD; // Лампа аварии
Lamp_Confirmation_C: WORD; // Лампа квитирования
Buzzer_C: WORD; // Управление звонком
END_VAR
VAR
Alarm_Not_Sound_Off: BOOL;
Alarm_Not_Confirm: BOOL;
R_TR1: R_TRIG;
R_TR2: R_TRIG;
R_TR3: R_TRIG;
END_VAR
(*----- IMPLEMENTATION -----*)
R_TR1(CLK:=Confirmation); IF R_TR1.Q THEN Alarm_Not_Confirm:=0; END_IF;
R_TR2(CLK:=Sound_Off); IF R_TR2.Q THEN Alarm_Not_Sound_Off:=0; END_IF;
R_TR3(CLK:=Alarm); IF R_TR3.Q AND ControlState_On THEN Alarm_Not_Confirm:=1; Alarm_Not_Sound_Off:=1; END_IF;
IF NOT ControlState_On THEN Alarm_Not_Confirm:=0; Alarm_Not_Sound_Off:=0; END_IF;
IF NOT Alarm AND NOT Alarm_Not_Confirm THEN Lamp_Alarm_C:=0; Lamp_Confirmation_C:=0; END_IF;
IF Alarm AND NOT Alarm_Not_Confirm THEN Lamp_Alarm_C:=1; Lamp_Confirmation_C:=0; END_IF;
IF Alarm_Not_Confirm THEN Lamp_Alarm_C:=2; Lamp_Confirmation_C:=1; END_IF;
IF Alarm_Not_Sound_Off THEN Buzzer_C:=2; ELSE Buzzer_C:=0; END_IF;
END_FUNCTION_BLOCK
+45
View File
@@ -0,0 +1,45 @@
(*
===============================================================================
Project : PLC_Library
Device : -
Path : Общие
Name : HYST
Type : FUNCTION_BLOCK
Exported : 2026-07-31 11:16:16
===============================================================================
*)
FUNCTION_BLOCK HYST
VAR_INPUT
In : REAL;
ON : REAL;
OFF : REAL;
END_VAR
VAR_OUTPUT
Q : BOOL;
win : BOOL;
END_VAR
(*----- IMPLEMENTATION -----*)
IF ON >= OFF THEN
IF IN < OFF THEN
Q := FALSE;
WIN := FALSE;
ELSIF IN > ON THEN
Q := TRUE;
WIN := FALSE;
ELSE
WIN := TRUE;
END_IF;
ELSE
IF IN > OFF THEN
Q := FALSE;
WIN := FALSE;
ELSIF IN < ON THEN
Q := TRUE;
WIN := FALSE;
ELSE
WIN := TRUE;
END_IF;
END_IF;
END_FUNCTION_BLOCK
+27
View File
@@ -0,0 +1,27 @@
(*
===============================================================================
Project : PLC_Library
Device : -
Path : Общие
Name : Norm_real
Type : FUNCTION
Exported : 2026-07-31 11:16:16
===============================================================================
*)
FUNCTION Norm_real : REAL
(*
Нормирует значение аналогового входа X по двум заданным граничным точкам нормировки (X1,Y1) (X2,Y2)
*)
VAR_INPUT
X: REAL;
X1: REAL;
Y1: REAL;
X2: REAL;
Y2: REAL;
END_VAR
(*----- IMPLEMENTATION -----*)
IF (X2-X1 = 0) THEN Norm_real:=Y1; RETURN; END_IF;
Norm_real:=(X-X1)*(Y2-Y1)/(X2-X1)+Y1;
END_FUNCTION
+125
View File
@@ -0,0 +1,125 @@
(*
===============================================================================
Project : PLC_Library
Device : -
Path : Общие
Name : PIDcontrol
Type : FUNCTION_BLOCK
Exported : 2026-07-31 11:16:16
===============================================================================
*)
FUNCTION_BLOCK PIDcontrol (* ПИД-регулятор. *)
VAR_INPUT
ProcessVariable: REAL := 0.0; (* Измеренное значение параметра *)
Setpoint: REAL := 0.0; (* Заданное значение *)
Kp: REAL := 0.001; (* Пропорциональный коэффициент *)
Ki: REAL := 0.001; (* Интегральный коэффициент *)
Kd: REAL := 0.0; (* Дифференциальный коэффициент *)
Kdf: REAL := 1.0; (* Коэффициент фильтрации (1/Tdf) *)
DBmax: REAL := 0.01; (* Верхняя граница зоны нечувствительности *)
DBmin: REAL := - 0.01; (* Нижняя граница зоны нечувствительности *)
OutMax: REAL := 100.0; (* Максимальный выход *)
OutMin: REAL := 0.0; (* Минимальный выход *)
Ts: REAL := 0.1; (* Время дискретизации [с] *)
Manual: REAL := 25.0; (* Значение в ручном режиме *)
ManOn: BOOL := FALSE; (* Флаг ручного режима *)
Reset: BOOL := FALSE; (* Сброс интегратора *)
AntiWindup: BOOL := TRUE; (* Включить антивиндап *)
END_VAR
VAR_OUTPUT
Out: REAL := 0.0; (* Выходной сигнал *)
Err: REAL := 0.0; (* Ошибка регулирования *)
OutLimited: BOOL := FALSE; (* Флаг ограничения выхода *)
END_VAR
VAR (* Внутренние переменные, сохраняемые. *)
Er: REAL := 0.0; (* Текущая ошибка *)
Ppart: REAL := 0.0; (* Пропорциональная часть *)
Ipart: REAL := 0.0; (* Интегральная часть *)
Dpart: REAL := 0.0; (* Дифференциальная часть *)
PrevEr: REAL := 0.0; (* Ошибка на предыдущем шаге (для дифференциатора). *)
FirstScan: BOOL := TRUE; (* Флаг первого сканирования. *)
END_VAR
VAR_TEMP
Auto: REAL; (* Выход ПИД *)
Sw: REAL; (* Промежуточное значение *)
END_VAR
(*----- IMPLEMENTATION -----*)
(* === ИНИЦИАЛИЗАЦИЯ И СБРОС === *)
IF Reset OR FirstScan THEN
Ipart := 0.0;
Dpart := 0.0;
PrevEr := 0.0;
FirstScan := FALSE;
END_IF;
(* === ПРОВЕРКА ВХОДНЫХ ПАРАМЕТРОВ === *)
IF (OutMin >= OutMax) OR (DBmin >= DBmax) OR (Ts <= 0) THEN
Out := 0.0;
OutLimited := TRUE;
RETURN;
END_IF;
(* === РАСЧЕТ ОШИБКИ === *)
Er := Setpoint - ProcessVariable;
Err := Er;
(* ЗОНА НЕЧУВСТВИТЕЛЬНОСТИ *)
IF (DBmin < Er) AND (Er < DBmax) THEN
Er := 0.0;
END_IF;
(* === ПРОПОРЦИОНАЛЬНАЯ ЧАСТЬ === *)
Ppart := Kp * Er;
(* === ИНТЕГРАЛЬНАЯ ЧАСТЬ === *)
IF Ki <> 0.0 THEN
Ipart := Ipart + (Ki * Er * Ts);
Ipart := LIMIT(OutMin, Ipart, OutMax);
ELSE
Ipart := 0.0;
END_IF;
(* === ДИФФЕРЕНЦИАЛЬНАЯ ЧАСТЬ (фильтрованная) === *)
IF Kd <> 0.0 THEN
Dpart := Kd * Kdf * (Er - PrevEr) - Kdf * Dpart * Ts;
PrevEr := Er; (* Сохраняем ошибку для следующего шага *)
ELSE
Dpart := 0.0;
END_IF;
(* === ВЫЧИСЛЕНИЕ ВЫХОДА === *)
Auto := Ppart + Ipart + Dpart;
(* === РЕЖИМ РУЧНОЙ/АВТОМАТИЧЕСКИЙ === *)
IF ManOn THEN
Sw := Manual;
(* Сброс интегратора при переходе в ручной режим *)
IF AntiWindup THEN
Ipart := Sw - (Ppart + Dpart);
END_IF;
ELSE
Sw := Auto;
END_IF;
(* === ОГРАНИЧЕНИЕ ВЫХОДА И АНТИВИНДАП === *)
IF Sw >= OutMax THEN
Out := OutMax;
OutLimited := TRUE;
IF AntiWindup AND NOT ManOn THEN
Ipart := OutMax - (Ppart + Dpart);
END_IF;
ELSIF Sw <= OutMin THEN
Out := OutMin;
OutLimited := TRUE;
IF AntiWindup AND NOT ManOn THEN
Ipart := OutMin - (Ppart + Dpart);
END_IF;
ELSE
Out := Sw;
OutLimited := FALSE;
END_IF;
END_FUNCTION_BLOCK
+32
View File
@@ -0,0 +1,32 @@
(*
===============================================================================
Project : PLC_Library
Device : -
Path : Общие
Name : Pulse_Switch
Type : FUNCTION_BLOCK
Exported : 2026-07-31 11:16:16
===============================================================================
*)
FUNCTION_BLOCK Pulse_Switch
VAR
R_tr_1: R_TRIG;
F_tr_1: F_TRIG;
tp_on: TP:=(PT:=t#500ms);
tp_off: TP:=(PT:=t#500ms);
END_VAR
VAR_INPUT
Switch_ctrl: BOOL;
END_VAR
VAR_OUTPUT
Switch_on: BOOL;
Switch_off: BOOL;
END_VAR
(*----- IMPLEMENTATION -----*)
R_tr_1(CLK:=Switch_ctrl);
tp_on(IN:=R_tr_1.Q, Q=>Switch_on);
F_tr_1(CLK:=Switch_ctrl);
tp_off(IN:=F_tr_1.Q, Q=>Switch_off);
END_FUNCTION_BLOCK
+55
View File
@@ -0,0 +1,55 @@
(*
===============================================================================
Project : PLC_Library
Device : -
Path : Общие
Name : STACK_I16
Type : FUNCTION_BLOCK
Exported : 2026-07-31 11:16:16
===============================================================================
*)
FUNCTION_BLOCK STACK_I16
(* стек на 16 элементов типа INT*)
VAR_INPUT
Din : INT; (* Переменная для записи в стек *)
E : BOOL := TRUE;(* Включение стека *)
POP : BOOL; (* Извлечение из стека *)
PUSH : BOOL; (* Запись в стек *)
RST : BOOL; (* Обнуление стека *)
END_VAR
VAR_OUTPUT
Dout : INT;
EMPTY : BOOL := TRUE;
FULL : BOOL;
END_VAR
VAR
stack: ARRAY[0..n] OF INT;
pt : INT;
END_VAR
VAR CONSTANT
n : INT := 15; (* changing this value will chage the number of stored elements in the fifo *)
END_VAR
(*----- IMPLEMENTATION -----*)
IF RST THEN
(* asynchronous reset for the fifo *)
pt := 0;
EMPTY := TRUE;
FULL := FALSE;
Dout := 0;
ELSIF E THEN
IF NOT EMPTY AND POP THEN
pt := pt - 1;
Dout := stack[pt];
EMPTY := pt = 0;
FULL := FALSE;
END_IF;
IF NOT FULL AND PUSH THEN
stack[pt] := Din;
pt := pt + 1;
FULL := pt > n;
EMPTY := FALSE;
END_IF;
END_IF;
END_FUNCTION_BLOCK
+99
View File
@@ -0,0 +1,99 @@
(*
===============================================================================
Project : PLC_Library
Device : -
Path : Общие
Name : STATUS_ANALOG_M
Type : FUNCTION_BLOCK
Exported : 2026-07-31 11:16:16
===============================================================================
*)
FUNCTION_BLOCK STATUS_ANALOG_M
(*
Модуль формирования статуса
Гистерезис по отключению и задержка по включению, вход типа REAL
-1 - нет связи с датчиком
0 - не определено
1 - норма
2 - предупредительный по нижнему уровню
3 - аварийный по нижнему уровню
4 - предупредительный по верхнему уровню,
5 - аварийный по верхнему уровню
*)
VAR_INPUT
Input: REAL;
fail_hi: REAL:=3.402823466E+38;
delta_fail_hi: REAL := 0;
time_fail_hi: TIME :=t#0s;
warn_hi: REAL:=3.402823466E+38;
delta_warn_hi: REAL := 0;
time_warn_hi: TIME :=t#0s;
warn_low: REAL:=-3.402823466E+38;
delta_warn_low: REAL := 0;
time_warn_low: TIME :=t#0s;
fail_low: REAL:=-3.402823466E+38;
delta_fail_low: REAL := 0;
time_fail_low: TIME :=t#0s;
no_signal: REAL:=-3.402823466E+38;
delta_no_signal: REAL := 0;
time_no_signal: TIME :=T#0S;
In_fail_hi: BOOL := FALSE;
In_warn_hi: BOOL := FALSE;
In_warn_low: BOOL := FALSE;
In_fail_low: BOOL := FALSE;
In_no_signal: BOOL := FALSE;
END_VAR
VAR_OUTPUT
Status: AnalogValueState;
END_VAR
VAR
fail_hi_st: BOOL;
warn_hi_st: BOOL;
normal_st: BOOL;
warn_low_st: BOOL;
fail_low_st: BOOL;
no_signal_st: BOOL;
TON_fail_hi: TON;
TON_warn_hi: TON;
TON_warn_low: TON;
TON_fail_low: TON;
TON_no_signal: TON;
END_VAR
(*----- IMPLEMENTATION -----*)
TON_no_signal(IN := (Input <= no_signal) OR In_no_signal, PT := time_no_signal);
IF TON_no_signal.Q THEN no_signal_st := TRUE; ELSIF (Input > no_signal + delta_no_signal) THEN no_signal_st := FALSE; END_IF;
TON_fail_low(IN := ((Input <= fail_low) AND NOT(no_signal_st)) OR In_fail_low, PT := time_fail_low);
IF TON_fail_low.Q THEN fail_low_st := TRUE; ELSIF (Input > fail_low + delta_fail_low) THEN fail_low_st := FALSE; END_IF;
TON_warn_low(IN := ((Input <= warn_low) AND NOT(no_signal_st) AND NOT(TON_fail_low.Q)) OR In_warn_low, PT := time_warn_low);
IF TON_warn_low.Q THEN warn_low_st := TRUE; ELSIF (Input > warn_low + delta_warn_low) THEN warn_low_st := FALSE; END_IF;
TON_fail_hi(IN := ((Input >= fail_hi) AND NOT(no_signal_st)) OR In_fail_hi, PT := time_fail_hi);
IF TON_fail_hi.Q THEN fail_hi_st := TRUE; ELSIF (Input < fail_hi - delta_fail_hi) THEN fail_hi_st := FALSE; END_IF;
TON_warn_hi(IN := ((Input >= warn_hi) AND NOT(no_signal_st) AND NOT(TON_fail_hi.Q)) OR In_warn_hi, PT := time_warn_hi);
IF TON_warn_hi.Q THEN warn_hi_st := TRUE; ELSIF (Input < warn_hi - delta_warn_hi) THEN warn_hi_st := FALSE; END_IF;
normal_st := (NOT(no_signal_st) AND NOT(fail_low_st) AND NOT(warn_low_st) AND NOT(warn_hi_st) AND NOT(fail_hi_st));
IF no_signal_st THEN
Status := AnalogValueState.no_signal;
ELSIF fail_hi_st THEN
Status := AnalogValueState.fail_hi;
ELSIF fail_low_st THEN
Status := AnalogValueState.fail_low;
ELSIF warn_hi_st THEN
Status := AnalogValueState.warn_hi;
ELSIF warn_low_st THEN
Status := AnalogValueState.warn_low;
ELSIF normal_st THEN
Status := AnalogValueState.normal;
ELSE
Status := AnalogValueState.undefined;
END_IF;
END_FUNCTION_BLOCK
+102
View File
@@ -0,0 +1,102 @@
(*
===============================================================================
Project : PLC_Library
Device : -
Path : Общие
Name : STATUS_ANALOG_M_I
Type : FUNCTION_BLOCK
Exported : 2026-07-31 11:16:16
===============================================================================
*)
FUNCTION_BLOCK STATUS_ANALOG_M_I
(*
Модуль формирования статуса
Гистерезис по отключению и задержка по включению, вход типа INT
-1 - нет связи с датчиком
0 - не определено
1 - норма
2 - предупредительный по нижнему уровню
3 - аварийный по нижнему уровню
4 - предупредительный по верхнему уровню,
5 - аварийный по верхнему уровню
*)
VAR_INPUT
Input: INT;
fail_hi: INT:=32767;
delta_fail_hi: INT := 0;
time_fail_hi: TIME :=t#0s;
warn_hi: INT:=32767;
delta_warn_hi: INT := 0;
time_warn_hi: TIME :=t#0s;
warn_low: INT:=-32768;
delta_warn_low: INT := 0;
time_warn_low: TIME :=t#0s;
fail_low: INT:=-32768;
delta_fail_low: INT := 0;
time_fail_low: TIME :=t#0s;
no_signal: INT:=-32768;
delta_no_signal: INT := 0;
time_no_signal: TIME :=T#0S;
In_fail_hi: BOOL := FALSE;
In_warn_hi: BOOL := FALSE;
In_warn_low: BOOL := FALSE;
In_fail_low: BOOL := FALSE;
In_no_signal: BOOL := FALSE;
END_VAR
VAR_OUTPUT
Status: AnalogValueState;
END_VAR
VAR
(* !!! ВНУТРЕННИЕ ВЫХОДНЫЕ ПЕРЕМЕННЫЕ!!! *)
fail_hi_st: BOOL;
warn_hi_st: BOOL;
normal_st: BOOL;
warn_low_st: BOOL;
fail_low_st: BOOL;
no_signal_st: BOOL;
(* !!! ВНУТРЕННИЕ НЕВЫХОДНЫЕ ПЕРЕМЕННЫЕ!!! *)
TON_fail_hi: TON;
TON_warn_hi: TON;
TON_warn_low: TON;
TON_fail_low: TON;
TON_no_signal: TON;
END_VAR
(*----- IMPLEMENTATION -----*)
TON_no_signal(IN := (Input <= no_signal) OR In_no_signal, PT := time_no_signal);
IF TON_no_signal.Q THEN no_signal_st := TRUE; ELSIF (Input > no_signal + delta_no_signal) THEN no_signal_st := FALSE; END_IF;
TON_fail_low(IN := ((Input <= fail_low) AND NOT(no_signal_st)) OR In_fail_low, PT := time_fail_low);
IF TON_fail_low.Q THEN fail_low_st := TRUE; ELSIF (Input > fail_low + delta_fail_low) THEN fail_low_st := FALSE; END_IF;
TON_warn_low(IN := ((Input <= warn_low) AND NOT(no_signal_st) AND NOT(TON_fail_low.Q)) OR In_warn_low, PT := time_warn_low);
IF TON_warn_low.Q THEN warn_low_st := TRUE; ELSIF (Input > warn_low + delta_warn_low) THEN warn_low_st := FALSE; END_IF;
TON_fail_hi(IN := ((Input >= fail_hi) AND NOT(no_signal_st)) OR In_fail_hi, PT := time_fail_hi);
IF TON_fail_hi.Q THEN fail_hi_st := TRUE; ELSIF (Input < fail_hi - delta_fail_hi) THEN fail_hi_st := FALSE; END_IF;
TON_warn_hi(IN := ((Input >= warn_hi) AND NOT(no_signal_st) AND NOT(TON_fail_hi.Q)) OR In_warn_hi, PT := time_warn_hi);
IF TON_warn_hi.Q THEN warn_hi_st := TRUE; ELSIF (Input < warn_hi - delta_warn_hi) THEN warn_hi_st := FALSE; END_IF;
normal_st := (NOT(no_signal_st) AND NOT(fail_low_st) AND NOT(warn_low_st) AND NOT(warn_hi_st) AND NOT(fail_hi_st));
IF no_signal_st THEN
Status := AnalogValueState.no_signal;
ELSIF fail_hi_st THEN
Status := AnalogValueState.fail_hi;
ELSIF fail_low_st THEN
Status := AnalogValueState.fail_low;
ELSIF warn_hi_st THEN
Status := AnalogValueState.warn_hi;
ELSIF warn_low_st THEN
Status := AnalogValueState.warn_low;
ELSIF normal_st THEN
Status := AnalogValueState.normal;
ELSE
Status := AnalogValueState.undefined;
END_IF;
END_FUNCTION_BLOCK
@@ -0,0 +1,39 @@
(*
===============================================================================
Project : PLC_Library
Device : -
Path : Общие
Name : Status_Connect_Counter
Type : FUNCTION_BLOCK
Exported : 2026-07-31 11:16:16
===============================================================================
*)
FUNCTION_BLOCK Status_Connect_Counter
(* Статус связи с СВУ по счетчику*)
VAR_INPUT
Counter: WORD;
T_Error: TIME; (* время для диагностирования ошибки*)
END_VAR
VAR_OUTPUT
CounterIsChanged: BOOL;
ERROR_CONNECT: BOOL;
END_VAR
VAR
CounterOld: WORD;
TON_SU: TON;
END_VAR
(*----- IMPLEMENTATION -----*)
TON_SU(IN:=(Counter = CounterOld), PT:=T_Error);
ERROR_CONNECT:=TON_SU.Q;
IF(Counter <> CounterOld) THEN
CounterIsChanged:=TRUE;
ELSE
CounterIsChanged:=FALSE;
END_IF
CounterOld:=Counter;
END_FUNCTION_BLOCK
@@ -0,0 +1,30 @@
(*
===============================================================================
Project : PLC_Library
Device : -
Path : Общие
Name : Status_SU_Connect
Type : FUNCTION_BLOCK
Exported : 2026-07-31 11:16:16
===============================================================================
*)
FUNCTION_BLOCK Status_SU_Connect
(* Статус связи с СВУ по серцебиению*)
VAR_INPUT
HeartBit: BOOL;
T_Pulse: TIME;
END_VAR
VAR_OUTPUT
ERROR_CONNECT: BOOL;
END_VAR
VAR
TON_SU_1: TON;
TON_SU_2: TON;
END_VAR
(*----- IMPLEMENTATION -----*)
TON_SU_1(IN:=HeartBit, PT:=T_Pulse);
TON_SU_2(IN:=NOT HeartBit, PT:=T_Pulse);
ERROR_CONNECT:=TON_SU_1.Q OR TON_SU_2.Q;
END_FUNCTION_BLOCK
+68
View File
@@ -0,0 +1,68 @@
(*
===============================================================================
Project : PLC_Library
Device : -
Path : Общие
Name : TOF_RST
Type : FUNCTION_BLOCK
Exported : 2026-07-31 11:16:16
===============================================================================
*)
FUNCTION_BLOCK TOF_RST
VAR_INPUT
IN: BOOL; // Управляющий сигнал
PT: TIME; // Время задержки выключения
RST: BOOL; // Принудительный сброс
END_VAR
VAR_OUTPUT
Q: BOOL; // Выход
ET: TIME; // Время работы таймера
END_VAR
VAR
_ton: TON;
prevIN: BOOL; // предыдущее состояние IN для детектирования фронта
timerRunning: BOOL; // TRUE идёт отсчёт задержки
END_VAR
(*----- IMPLEMENTATION -----*)
// Принудительный сброс наивысший приоритет
IF RST THEN
Q := FALSE;
timerRunning := FALSE;
prevIN := FALSE; // после RST не ловим задний фронт
_ton(IN := FALSE, PT := PT);
ET := _ton.ET;
RETURN;
END_IF
// Передний фронт IN отменяем задержку
IF IN AND NOT prevIN THEN
timerRunning := FALSE;
END_IF
// Задний фронт IN запускаем задержку
IF NOT IN AND prevIN THEN
timerRunning := TRUE;
END_IF
prevIN := IN;
// Запуск/работа таймера
_ton(IN := timerRunning, PT := PT);
ET := _ton.ET;
// Логика выхода
IF IN THEN
Q := TRUE;
timerRunning := FALSE;
ELSIF timerRunning THEN
IF _ton.Q THEN
Q := FALSE;
timerRunning := FALSE;
ELSE
Q := TRUE;
END_IF
ELSE
Q := FALSE;
END_IF
END_FUNCTION_BLOCK
+32
View File
@@ -0,0 +1,32 @@
(*
===============================================================================
Project : PLC_Library
Device : -
Path : Общие
Name : TONOF
Type : FUNCTION_BLOCK
Exported : 2026-07-31 11:16:16
===============================================================================
*)
FUNCTION_BLOCK TONOF
(*
TONOF генерирует TON и TOF задержки для переменной IN
Задержка на вход T_ON, задержка на выход T_OFF
*)
VAR_INPUT
IN : BOOL;
T_ON : TIME := T#0s; (* Задержка на вход *)
T_OFF : TIME := T#0s; (* Задержка на выход *)
END_VAR
VAR_OUTPUT
Q : BOOL;
END_VAR
VAR
X : TON;
END_VAR
(*----- IMPLEMENTATION -----*)
X(IN := IN XOR Q, PT := SEL(IN,T_OFF,T_ON));
IF X.Q THEN Q := IN; END_IF;
END_FUNCTION_BLOCK
+60
View File
@@ -0,0 +1,60 @@
(*
===============================================================================
Project : PLC_Library
Device : -
Path : Общие
Name : TP_RST
Type : FUNCTION_BLOCK
Exported : 2026-07-31 11:16:16
===============================================================================
*)
FUNCTION_BLOCK TP_RST
VAR_INPUT
IN: BOOL; // Управляющий сигнал
PT: TIME; // Длительность импульса
RST: BOOL; // Принудительный сброс
END_VAR
VAR_OUTPUT
Q: BOOL; // Выход
ET: TIME; // Прошедшее время импульса
END_VAR
VAR
_ton: TON;
prevIN: BOOL; // Предыдущее состояние IN
timerRunning: BOOL; // TRUE идёт отсчёт импульса
END_VAR
(*----- IMPLEMENTATION -----*)
// Принудительный сброс наивысший приоритет
IF RST THEN
Q := FALSE;
timerRunning := FALSE;
prevIN := FALSE;
_ton(IN := FALSE, PT := PT);
ET := _ton.ET;
RETURN;
END_IF
// Передний фронт IN запускаем импульс (только если не идёт уже)
IF IN AND NOT prevIN AND NOT timerRunning THEN
timerRunning := TRUE;
END_IF
prevIN := IN;
// Таймер вызывается каждый цикл
_ton(IN := timerRunning, PT := PT);
ET := _ton.ET;
// Логика выхода
IF timerRunning THEN
IF _ton.Q THEN
Q := FALSE;
timerRunning := FALSE;
ELSE
Q := TRUE;
END_IF
ELSE
Q := FALSE;
END_IF
END_FUNCTION_BLOCK