Tips für PICs 18: Warte-Unterprogramm
in einer Multi-Tasking-Umgebung

Wie schon an anderer Stelle beschrieben, darf ein Programm, das mehrere Ereignisse quasi-gleichzeitig bearbeiten soll (Multi-tasking), nirgends angehalten werden. In dieser Zeit wäre es "blind" oder für andere Ereignisse "taub".
Es gibt aber durchaus Anlässe, bei denen gewartet werden muss. Beispiel: ich öffne eine Stoppstelle und muss dann warten, bis das angehaltene Auto sie sicher verlassen hat, bevor ich sie wieder schließen darf. Ich darf sie aber auch nicht allzu lange offen halten, da dann evtl. das nächste Auto durchfährt.

Für das Folgende ist es unbedingt wichtig, dass Sie sich in der Struktur und den Funktionen eines PIC gut auskennen und schon etliche Programme geschrieben haben.

Wir wollen Ihnen hier ein Programm-Schnipsel (UP "Warten") vorstellen, mit dem das Warten bei uns gelöst worden ist. Es benötigt zwei Variable: einmal eine Zeit-Variable (mit der gewartet werden soll) und einen Zwischenspeicher. Dazu kommt noch ein Merk-Bit, das zum Feststellen dient, dass die geplante Zeit abgelaufen ist. Die Zeit-Variable wird in der Interrupt-Routine (ISR) im Sekundentakt bis auf genau 0 heruntergezählt, aber nicht weiter. Beim Übergang von 1 auf 0 wird dort das Merk-Bit gesetzt. Dieser Vorgang wird ständig während der gesamten Laufzeit des PIC ausgeführt. Das bedeutet aber auch, dass in Ruhezeiten, in denen nicht gewartet werden soll, in der ISR auch nicht gezählt wird, also auch das Merk-Bit nicht gesetzt wird.
Die Zeit-Variable haben wir "warze" genannt, den Zwischenspeicher "rett".
Das Merk-Bit soll in der Variablen "merk" an der Stelle "bit" stehen.

Zunächst die Flussdiagramme:
ISR UP

HP Das Unterprogramm fragt "warze" ab. Wenn dessen Wert 0 ist, kann es sein, dass entweder die Wartezeit noch nicht gestartet ist, oder dass sie gerade beendet worden ist. Dies lässt sich an dem Merk-Bit feststellen: ist es auf 1 gesetzt, wurde "warze" gerade eben fertig heruntergezählt; ist es 0, dann wurde die Wartezeit noch nicht gestartet. In letzterem Fall wird "warze" mit dem übergebenen Wert geladen, d.h.: dadurch wird die Wartezeit gestartet.
Das Unterprogramm erzeugt 2 Ergebnisse, entweder "Wartezeit läuft" oder "Wartezeit ist beendet". Diese werden durch Z=0 oder Z=1 gekennzeichnet. Dabei ist Z das "zero-flag" im STATUS-Register, das das Ergebnis "Null" einer Operation darstellt. Hier wird es zur Informations-Weitergabe benutzt. Nach Rückkehr aus dem Unterprogramm muss dieses flag natürlich abgefragt werden.
Das Unterprogramm wird wie folgt verwendet: Ich lade das w-Register mit der Wartezeit und starte dann das Unterprogramm. Anschließend frage ich ab, ob diese Zeit schon abgelaufen ist, und setze mein Programm entsprechend fort. Das war's schon.

Die Befehlsfolge in diesem Beispiel für die ISR (nach der Untersetzung auf 1-sec-Takt):
(Hier haben wir die Wartezeit noch "zeit" genannt und noch nicht "warze")
ISRCode

für das Unterprogramm:
UPCode

für das Hauptprogramm (wir wollen hier 2 sec warten):
HPCode

Die Zeitverzögerung in diesem Beispiel geht von 1 bis 255 sec. Wenn Sie kleinere Zeiten brauchen: kein Problem. Dann setzen Sie einfach den Takt in der ISR auf (z.B.) 0,1 sec. Und schon haben Sie Wartezeiten von 0,1 sec bis 25,5 sec zur Verfügung.
Wir wiederholen hier noch einmal: da die ISR und das Hauptprogramm nicht synchron laufen, kann es sein, dass das erste Herunterzählen von "warze" fast sofort nach dem Starten erfolgt. Daher ist es nicht zweckmäßig, mit Wartezeiten von "1" zu arbeiten.
Noch ein Beispiel: wir wollen blinken, mit ca. 1 Hz. Dann müsste der Takt in der ISR auf 0,1 sec gesetzt werden, das Warte-UP mit "5" in w gestartet werden, und statt der "nop"s müsste ein Ausgangs-Pin ein- und ausgeschaltet werden, z.B. mit einem EXOR-Befehl.

Für weitere Fragen stehen gern zur Verfügung:
- der MEC; Besichtigung und Fachsimpelei z.B. an unseren "Club-Abenden"
- der Autor: Hans Peter Kastner

Version vom 28.12.2025; erstellt am 14.04.2025
Copyright © 2025 by Modelleisenbahnclub Castrop-Rauxel 1987 e.V.

Valid HTML 4.01!