Die Programmsteuerung
- Sprungmarken und Subroutinen
- Gruppierungen
- FOR NEXT Schleifen
- Schrittsteuerungen mit Statusbits
- Ablaufsteuerungen mit Sequence Blocks
- Interrupts
Sprungmarken und Subroutinen
Sprungmarken werden in der XC Serie mit P benannt, P0 bis P9999 stehen zur freien Verfügung. Es gibt zwei Möglichkeiten Sprungmarken anzuspringen, einmal über CJ (Conditional Jump, bedingter Sprung) und einmal über CALL (Subroutinenaufruf). Beide Befehle werden über einen beliebigen Kontakt aufgerufen. CJ springt direkt zur Sprungmarke und führt das Programm dort weiter aus. Der Befehl eignet sich zum Überspringen bestimmter Bereiche zur Verkürzung der Zykluszeit.
Mit CALL wird eine Marke P als Subroutine aufgerufen, am Ende der Subroutine wird ein SRET gesetzt, um zum Hauptprogramm zurückzukehren. Der Inhalt zwischen Subroutinen lässt sich in XCPPro über ein Minuszeichen links neben der Marke zusammenklappen. Damit wird das Programm übersichtlicher dargestellt. Wichtig: Damit die Subroutinen nicht ausgeführt werden, ohne dass sie mit CALL aufgerufen werden, muss das Hauptprogramm mit FEND beendet werden, bevor der Abschnitt der Subroutinen beginnt. FEND markiert das Ende des Hauptprogramms, der Zyklus beginnt von vorn. Das gleiche gilt übrigens für Interruptroutinen, auch die müssen im Bereich hinter FEND stehen, sonst werden sie auch ohne Interrupt ausgeführt (siehe unten).
Im Beispiel rechts wird Zeile 4 übersprungen, solande M1 geöffnet ist. Bereich P2 wird nur ausgeführt, wenn auf M2 eine positive Flanke anliegt.
Gruppierungen
Zeilen, die inhaltlich zusammen gehören, können im Kontaktplan mit der Marke GROUP und der Endmarke GROUPE logisch zusammengefasst werden. Anweisungen in einer Gruppe können zusammengeklappt werden, um die Übersichtlichkeit zu erhöhen. Auf den Programmablauf haben Gruppierungen überhaupt keinen Einfluss.
FOR NEXT Schleifen
Mit For Next Schleifen können in der XC einfache Zählschleifen realisiert werden. Eine positive oder negative Flanke aktiviert die Schleife. Als Parameter wird die Anzahl der Durchgänge als Konstante oder über ein Register D übergeben. Next beendet die Schleife. Zählschleifen können bis zu 8 Ebenden tief verschachtelt werden.
Beispiel: Einfache Zählschleife, eine positive Flanke auf M1 lässt die Schleife 1000 mal durchlaufen, jeder Durchlauf erhöht D0 um eins.
Schrittsteuerung mit Statusbits
Um einfache Schrittsteuerungen zu realisieren gibt es mit S0 bis S1023 einen eigenen Speicherbereich. Die dazugehörigen Befehle sind SET, ST, STL und STLE. Mit STL S.. wird der Beginn der entsprechende Subroutine im Kontaktplan markiert, STLE beendet sie. STL S0 markiert also den Bereich, an dem die Anweisungen für Schritt S0 beginnen. Es gibt zwei Möglichkeiten, die Ausführung dieses Schritts zu aktivieren. SET S0 aktiviert Schritt S0 und deaktiviert den bisher aktiven Schritt. Wenn ich zum Beispiel S0 von S3 aus aufrufe, wird mit SET S0 der Schritt S0 aktiviert und S3 deaktiviert. Der Befehl ST S0 hingegen aktiviert S0 ohne den bisher aktiven Schritt zu deaktivieren. So lassen sich gleichzeitig mehrere Schritte parallel ausführen.
Beispiel: Einfache Schrittsteuerung, M1 aktiviert die Schrittkette, Schritt S0 aktiviert mit 1 Sekunde Verzögerung Schritt S1.
Ablaufsteuerungen mit Sequence Blocks
Um standardisierte Abläufe sequentiell abzuarbeiten bieten sich in XCPPro eigens dafür konzipierte Sequence Blocks an. Schrittketten, deren Schritte nacheinander ausgeführt werden sollen lassen sich in Sequence Blocks einfacher projektieren. Bei Verwendung der oben beschriebenen Statusbits müsste für jeden Schritt ein eigener Abschnitt angelegt werden und die Sprünge manuell eingefügt werden. In Sequence Blocks ist das wesentlich einfacher. Über einen Rechtsklick auf Sequence Blocks im Projektbaum links habt ihr die Möglichkeit, mit Add Sequence Block einen solchen Block hinzuzufügen. Im Block selbst könnt ihr nun über Add die verschiedenen Schritte hinzufügen:
- Common Item - erstellt einen Schritt in AWL, innerhalb des AWL-Texts können auch Bedingungen implementiert werden
- Pulse Output - gibt ein Muster an Ausgangsimpulsen aus
- Modbus Item - eine wirklich kinderleichte Möglichkeit in XCPPro Modbus-Kommunikation auszuführen, mehr dazu im Kapitel Kommunikation
- Frequency Inverter Item - erlaubt eine Anweisung an eine FU zu senden
- Free Format Communication Item - ermöglicht einfache serielle Kommunikation über die RS232/RS485 Schnittstelle
- Wait Item - implementiert eine Warteanweisung, die entweder auf ein Flag wartet oder einen der Timer setzt (siehe Kapitel Timer & Zähler zu den Timern)
Über das Attribut Skip kann ein Bit gesetzt werden, mit dem die Anweisung übersprungen wird. Über Upwards & Downwards kann die Abfolge der Schritte geändert werden. Die Schritte werden nacheinander ausgeführt. Das Ende eines Schritts leitet den nächsten ein, Transitionsbedingungen gibt es in den Sequence Blocks nicht. Für bedingte Abläufe ist die oben beschriebene Schrittsteuerung mit Statusbits geeignet.
Interrupts
In THINGET XC-Steuerungen gibt es drei Möglichkeiten Anweisungen mit hoher Priorität über Interrupts auszuführen: Zeitinterrupts, Interrupts über Präzisionstimer und Eingangsinterrupts. Interrupts unterbrechen den normalen Programmfluss und führen Anweisungen bei bestimmten Ereignissen sofort aus. Damit lassen sich besonders zeitkritische Aktionen ausführen. Im Hauptprogramm könnt ihr festlegen, welche Bereiche von Interrupts unterbrochen werden dürfen und welche nicht. EI (enable interrupts) lässt Interrupts zu. Das ist auch die Standardeinstellung. Mit DI (disable interrupts) können Bereiche markiert werden, die so wichtig sind, dass sie nicht unterbrochen werden dürfen. Am Ende dieses Bereichs könnt ihr über EI Interrupts wieder zulassen.
Normale Zeitinterrupts sind besonders einfach zu implementieren. Es gibt zehn von diesen Interrupts, I40** bis I49** . Implementiert werden sie einfach über die Anweisung I40nn, wobei nn für die Interruptzeit in ms steht. Danach folgen die Anweisungen, die durch diesen Interrupt ausgeführt werden sollen. Mit IRET wird dieser Bereich abgeschlossen. I4150 führt also als Zeitinterrupt den nachfolgenden Code alle 50 ms aus. Für die ersten drei Interrupts I40.. bis I42.. gibt es mit Merkern M8056 bis M8058 zusätzlich Bits, die diese Interrupts an und ausschalten können.
Die Interrupts der Präzisionstimer erlauben eine besonders zuverlässige und genaue Zeitsteuerung auch über Perioden über 100 ms hinaus. Die zehn Präzisionstimer liegen zwischen T600 bis T618, die Funktionsweise habt ihr im Kapitel Timer & Zähler kennengelernt. Über I3000 bis I3010 lassen sich die Präzisionstimer Interrupts implementieren. Auch diese Interruptanweisungen werden mit IRET beendet. Beispiel: schaltet der Präzisionstimerkontakt T602, wird die Interruptroutine zwischen I3001 und IRET ausgeführt.
In den CPU-Basisgeräten der XC3 und XC5 Serien sind einzelne Eingänge als Interrupteingänge ausgeführt: in der X3-14 ist es Eingang X7, in XC3-32 sind es X2, X5 und X10 und in der XC-60 sind es X6, X7 und X10. Falls ihr euch fragt, warum die Interrupts so unterschiedlich ausgeführt: frag ich mich auch. Für diese Eingänge gibt es jeweils einen Interrupt für die positive Flanke und einen für die negative Flanke. Für XC-14 X7 ist der positive Interrupt I0000 und der negative I0001. Die Anweisungen, die bei diesem Interrupt ausgeführt werden sollen, setzt ihr einfach zwischen Anweisung I0000 und IRET. Über Merker M8050 könnt ihr den Interrupt aktivieren und abschalten. Gibt es mehrere Interrupteinänge, werden die über I0100, I0200 usw. angesprochen und M8051, M8052 deaktiviert. Genaue Informationen dazu findet ihr am Ende von Kapitel 11 des Programmierhandbuchs.
Wichtig: Damit die Interruptroutinen nicht ausgeführt werden, ohne dass ein Interrupt vorliegt, muss das Hauptprogramm mit FEND beendet werden, bevor der Abschnitt der Interruptroutinen beginnt.
Beispiel: Einfache Interruptroutine. Zeile 1 wird nicht vom Eingangsinterrupt unterbrochen. FEND verhindert, dass die Interrupt-Routine auch ohne Interrupt ausgeführt wird.
Übung
Implementiert einen einfachen Zeitinterrupt, der einen Zähler per FOR NEXT Schleife alle 10 ms um 10 erhöht.