Step 7 Zyklusverteiler

SPSGreenhorn

Level-1
Beiträge
74
Reaktionspunkte
1
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo Zusammen,

ich hab einen Zyklusverteiler in SCL Programmiert. Kurz gesagt mein Cyclic interrupt wird all 10ms aufgerufen bei 10 Reglern will ich das halt jeder Regler in Exakt 100ms Zyklus aufgerufen wird.

Code:
"ProgramData".Zykluszeit := T#100MS;


IF "ProgramData".Zyklusteiler = 0 THEN
    "Regler1"(RESET := FALSE,
                     CYCLE := "ProgramData".Zykluszeit);
    "ProgramData".Zyklusteiler := 1;
    
ELSIF "ProgramData".Zyklusteiler = 1 THEN
    "Regler2"(RESET := FALSE,
                     CYCLE := "ProgramData".Zykluszeit);
    "ProgramData".Zyklusteiler := 2;
...
...
ELSIF "ProgramData".Zyklusteiler = 9 THEN
    "Regler3_PCV_03"(RESET := FALSE,
                     CYCLE := "ProgramData".Zykluszeit);
    "ProgramData".Zyklusteiler := 0;

END_IF;

Jetzt meine Frage: Das Programm springt in die IF Schleife sobald Zyklusteiler==0 und setzt darauf Zyklusteiler = 1. Spring das Programm jetzt zum END_IF oder wird die nächste ELSIF Bedingung geprüft? Wenn ja würde der Zyklusteiler ja so nicht funktionieren und ich müsste noch eine art "Break" an das ende jeder Schleifenbedingung einfügen.

Danke im Voraus und Vorweihnachtliche Grüße,
euer Greenhorn.
 
Jetzt meine Frage: Das Programm springt in die IF Schleife sobald Zyklusteiler==0 und setzt darauf Zyklusteiler = 1. Spring das Programm jetzt zum END_IF oder wird die nächste ELSIF Bedingung geprüft? Wenn ja würde der Zyklusteiler ja so nicht funktionieren und ich müsste noch eine art "Break" an das ende jeder Schleifenbedingung einfügen.
Ja, die Programmabarbeitung wird mit der Anweisung hinter dem zugehörigen "END_IF;" fortgesetzt.

Eine Schleife sehe ich in dem von dir gezeigten Programmausschnitt nicht.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Du könntest stattdessen z.B. auch CASE verwenden und den Zyklusteiler nur an einer Stelle weiterschalten:
Code:
"ProgramData".Zykluszeit := T#100MS;

CASE "ProgramData".Zyklusteiler OF
  0:
    "Regler1"(RESET := FALSE, CYCLE := "ProgramData".Zykluszeit);
    
  1:
    "Regler2"(RESET := FALSE, CYCLE := "ProgramData".Zykluszeit);

...
...

  9:
    "Regler3_PCV_03"(RESET := FALSE, CYCLE := "ProgramData".Zykluszeit);

END_CASE;

"ProgramData".Zyklusteiler := ("ProgramData".Zyklusteiler + 1) MOD 10;
 
stimmt. aber macht den Code nicht viel schmaler. Mittlerweile ist mir auch klar das meine Frage nicht so viel sinn macht. Bei IF ELSIF ELSE Bedingungen kann immer nur EINE BEDINGUNG erfüllt werden. Sonst wären es ja einfache mehrere IF Bedingungen hintereinander.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Du könntest stattdessen z.B. auch CASE verwenden und den Zyklusteiler nur an einer Stelle weiterschalten
stimmt. aber macht den Code nicht viel schmaler.
Oh doch. Schau Dir mal die Größe des erzeugten Codes an.

Das CASE-Konstrukt ist effizienter und übersichtlicher und weniger Tippfehler-anfällig als 10 Vergleiche für IF/ELSIF.

Du solltest auch mindestens an einer Stelle prüfen/sicherstellen, daß "ProgramData".Zyklusteiler (danach) nur Werte 0..9 enthält. Sollte aus irgendeinem Grund da mal ein anderer Wert drin stehen, dann werden bei Deinem IF..THEN..ELSIF-Code die Regler nie mehr bearbeitet.

Wenn Du sowieso immer nur um 1 erhöhst, dann ist es effizienter/kürzer und Tippfehler-sicherer, das für alle Cases gemeinsam nur einmal am Anfang oder Ende des Codes zu tun und da auch für das Ergebnis garantiert 0..9 zu sorgen.

Harald
 
Zurück
Oben