//-> TYPE Uhr :
//-> STRUCT
//-> iAnzg : INT ; // für aUhr[iIdx].iAnzg
//-> iDiff : INT ; // für aUhr[iIdx].iDiff
//-> bPuls : BOOL ; // für aUhr[iIdx].bPuls
//-> END_STRUCT
//-> END_TYPE
VAR_OUTPUT
obUhr01Step : BOOL ;
obUhr02Step : BOOL ;
// u.s.w. ...
obUhr19Step : BOOL ;
obUhr20Step : BOOL ;
END_VAR
VAR
aiAnzg : ARRAY[1..20] OF INT ; // "Ersatz" für aUhr[iIdx].iAnzg [min]
aiDiff : ARRAY[1..20] OF INT ; // "Ersatz" für aUhr[iIdx].iDiff -60..659 [min]
abPuls : ARRAY[1..20] OF BOOL ; // "Ersatz" für aUhr[iIdx].bPuls
//-> aUhr : ARRAY[0..20] OF Uhr ; // ersetzt aiAnzg[] und aiDiff[] und abPuls[]
tbAusgTakt : BOOL ; // 0,5 Hz-Takt für Ansteuerung der Uhren
dtSollAnzgSec : DT ; // HilfsVariable für den eingelesenen Datums+Zeit-Wert [s]
iAnfMin : INT := -60 ; // "Konstante" max. 60 Minuten-Impulse unterdrücken
iIdxMaxUhr : INT := 20 ; // "Konstante" Index letzte Uhr
iIdxMinUhr : INT := 1 ; // "Konstante" Index erste Uhr
iSollAnzg : INT ; // aus DATE_AND_TIME extrahierte Zeit "00:00" .. "11:59" [min]
iIdx : INT ; // LaufVariable (Array-Index)
sbAusgTaktZuvo : BOOL ; // static, für FlankenErkennung AusgabeTakt
siSollAnzgZuvo : INT ; // static, für FlankenErkennung Zeit (hh:mm)
END_VAR
dtSollAnzgSec := ??? ; // <===<<< eingelesene Zeit mit Datum [s] (DT, DATE and TIME)
iIdxMinUhr := 1 ; // Index für erste Uhr
iIdxMaxUhr := 20 ; // Index für letzte Uhr
iAnfMin := -60 ; // AnfangsWert für iDiff z.B. -60..659, d.h. max 60 min warten statt Ehrenrunden ausgeben
iSollAnzg := DT_TO_INT ( ( dtSollAnzgSec / 60 ) MOD 720 ) ; // [min] begrenzt auf "00:00" .. "11:59"
// - - - < im MinutenTakt Abweichungen ermitteln und weitergeben > - - -
IF NOT siSollAnzgZuvo AND iSollAnzg THEN
FOR iIdx := iIdxMinUhr TO iIdxMaxUhr DO
IF NOT bPuls[iIdx] THEN // Anzahl Minuten-Impulse -60..659
//-> IF NOT aUhr[iIdx].bPuls THEN // Anzahl Minuten-Impulse -60..659 // ersetzt vorherige Zeile
iDiff[iIdx] := ( iSollAnzg - iAnzg[iIdx] - iAnfMin ) MOD 720 + iAnfMin ;
//-> aUhr[iIdx].iDiff := ( iSollAnzg - iAnzg[iIdx] - iAnfMin ) MOD 720 + iAnfMin ; // ersetzt vorherige Zeile
END_IF ;
END_FOR ;
END_IF ;
siSollAnzgZuvo := iSollAnzg ; // FlankenVariable aktualisieren
// - - - < im BlinkTakt (0,5 Hz) Pulse ausgeben > - - -
tbAusgTakt := ( dtSollAnzgSec MOD 2 ) = 0 ;
IF NOT sbAusgTaktZuvo XOR tbAusgTakt THEN // keine AusgTaktFlanke
; // nix
ELSIF tbAusgTakt THEN // pos. AusgTaktFlanke
FOR iIdx := iIdxMinUhr TO iIdxMaxUhr DO
IF iDiff[iIdx] > 0 THEN
//-> IF aUhr[iIdx].iDiff > 0 THEN // ersetzt vorherige Zeile
bPuls[iIdx] := TRUE ; // Puls starten
//-> aUhr[iIdx].bPuls := TRUE ; // Puls starten // ersetzt vorherige Zeile
END_IF ;
END_FOR ;
sbAusgTaktZuvo := tbAusgTakt ; // Flanken-"Merker" aktualisieren
ELSE // neg. AusgTaktFlanke
FOR iIdx := iIdxMinUhr TO iIdxMaxUhr DO
IF bPuls[iIdx] THEN // wenn PulsAusgabe für diese Uhr aktiv ist, dann ...
//-> IF aUhr[iIdx].bPuls THEN // wenn PulsAusgabe für diese Uhr aktiv ist, dann ... // ersetzt vorherige Zeile
iDiff[iIdx] := iDiff[iIdx] - 1 ; // Soll-Impulse dekrementieren
//-> aUhr[iIdx].iDiff := aUhr[iIdx].iDiff - 1 ; // Soll-Impulse dekrementieren // ersetzt vorherige Zeile
iAnzg[iIdx] := ( iAnzg[iIdx] + 1 ) MOD 720 ; // AnzeigeWert aktualisieren
//-> aUhr[iIdx].iAnzg := ( aUhr[iIdx].iAnzg + 1 ) MOD 720 ; // AnzeigeWert aktualisieren // ersetzt vorherige Zeile
bPuls[iIdx] := FALSE ; // und Puls beenden
//-> aUhr[iIdx].bPuls := FALSE ; // und Puls beenden // ersetzt vorherige Zeile
END_IF ;
END_FOR ;
sbAusgTaktZuvo := tbAusgTakt ; // Flanken-"Merker" aktualisieren
END_IF ;
// - - - < Ausgabe der Minuten-Impulse an die Peripherie > - - -
obUhr01Step := bPuls[1] ;
//-> obUhr01Step := aUhr[1].bPuls ; // ersetzt vorherige Zeile
obUhr02Step := bPuls[2] ;
//-> obUhr02Step := aUhr[2].bPuls ; // ersetzt vorherige Zeile
//
// u.s.w. ...
//
obUhr19Step := bPuls[19] ;
//-> obUhr19Step := aUhr[19].bPuls ; // ersetzt vorherige Zeile
obUhr20Step := bPuls[20] ;
//-> obUhr20Step := aUhr[20].bPuls ; // ersetzt vorherige Zeile