FUNCTION_BLOCK "H_System"
{ S7_Optimized_Access := 'TRUE' } // Optimierten Zugriff auf S7 aktivieren (Siemens spezifische Einstellung)
VERSION : 0.1
// Eingabevariablen
VAR_INPUT
LADDR_HSystem : HW_ANY; // Hardware-Adresse des H-Systems ("Local1~RHSystem")
END_VAR
// Interne Variablen
VAR
// Diagnosedaten und Betriebsmodi
DIS {InstructionName := 'DIS'; LibVersion := '1.0'; ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'; S7_SetPoint := 'False'} : DIS;
DNN {InstructionName := 'DNN'; LibVersion := '1.0'; ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'; S7_SetPoint := 'False'} : DNN;
// Modusvariable (1 Byte)
Mode { S7_SetPoint := 'True'} : Byte;
// Zeitgeber (Takt)
Takt {InstructionName := 'TON_TIME'; LibVersion := '1.0'} : TON_TIME;
// Flankenauswertung (R_TRIG)
Output {InstructionName := 'R_TRIG'; LibVersion := '1.0'} : R_TRIG;
// Struktur für Taktvariablen
stTakt : Struct
q : Bool; // Ausgang des Taktes
in : Bool; // Eingang des Taktes
END_STRUCT;
END_VAR
// Temporäre Variablen
VAR_TEMP
Status : Int; // Statusvariable
Busy : Bool; // Anzeige, ob eine Funktion gerade ausgeführt wird
RetVal : Int; // Rückgabewert von Diagnosefunktionen
subordinateState : UInt; // Untergeordneter Zustand
CNT_DIAG_temp : UInt; // Diagnosezähler (temporär)
MRP_proof_Off : Bool; // Zustand, ob MRP-Prüfung deaktiviert ist
END_VAR
// Konstante Variablen für Modusoperationen
VAR CONSTANT
Syncup_sperren : Byte := 3; // Syncup gesperrt
Syncup_MRP_freigeben : Byte := 4; // MRP-Freigabe für Syncup
Syncup_anfordern : Byte := 7; // Syncup anfordern
Syncup_anfrage_gesperrt : Byte := 10; // Syncup-Anfrage gesperrt
MRP_proof_deact : Byte := 14; // MRP-Prüfung deaktivieren
RUN_Redundant : UInt := 40; // Redundanter Betrieb
RUN_Solo : UInt := 37; // Solo-Betrieb
END_VAR
BEGIN
// Flankenerkennung, ob der Modus aktiv ist und der Takt nicht an ist
#Output(CLK:=(#Mode <> 0) AND NOT #stTakt.q);
// Taktgeber mit einer Zeit von 500 ms
#Takt(IN:=#stTakt.in, PT:=T#500ms, Q=>#stTakt.q);
// Takteingang setzen, wenn der Takt aus ist und der Modus nicht 0 ist
#stTakt.in := NOT #stTakt.q AND (#Mode <> 0);
// Steuerung des redundanten Systems (RH_CTRL)
#Status := RH_CTRL(REQ := #Output.Q, Mode := #Mode, Busy => #Busy);
// Diagnoseabfrage des Redundanz-/Hochverfügbarkeitsystems (Modus 2)
#RetVal := GET_DIAG(MODE := 2, LADDR := #LADDR_HSystem, CNT_DIAG => #CNT_DIAG_temp, DIAG := #DNN);
#subordinateState := #DNN.SubordinateState; // Untergeordneter Zustand aus den Diagnoseinformationen
#MRP_proof_Off := #DNN.SubordinateIOState.%X15; // MRP-Prüfung für Sync-Up deaktiviert (Bit 15)
// Diagnoseabfrage des Systems (Modus 1)
#RetVal := GET_DIAG(MODE := 1, LADDR := #LADDR_HSystem, CNT_DIAG => #CNT_DIAG_temp, DIAG := #DIS);
// Betriebszustand auswerten
CASE #DIS.OperatingState OF
#RUN_Solo:
// Im Solo-Betrieb und MRP Prüfung aktiv, aber fehlerhaft, dann MRP Prüfung deaktivieren
IF NOT #MRP_proof_Off AND (#subordinateState <> 0) THEN
#Mode := #MRP_proof_deact;
ELSE // Andernfalls Syncup anfordern
#Mode := #Syncup_anfordern;
END_IF;
#RUN_Redundant:
// Im redundanten Betrieb, wenn MRP deaktiviert ist, MRP freigeben
IF #MRP_proof_Off THEN
#Mode := #Syncup_MRP_freigeben;
// Andernfalls, wenn der Modus nicht 0 ist, auf 0 setzen
ELSIF (NOT #Mode = 0) THEN
#Mode := 0;
END_IF;
END_CASE;
END_FUNCTION_BLOCK