![]() |
MikrocomputertechnikProf. Jürgen Plate |
Bei diesem Versuch soll unter Verwendung der Ports B und C des M68HC11 Datenverkehr mit externen Komponenten durchgeführt werden. Es soll grundsätzlich im polling mode gearbeitet werden, d.h. ohne Unterbrechungen. Geeignete Programmteile sind als Unterprogramm zu formulieren. Zeichnen Sie immer zuerst ein Flussdiagramm und programmieren Sie dann danach.
Die Stellung der Schalter S7 - S4 soll andauernd über Port C [3:0] eingelesen und über Port C [7:4] auf die LEDs L3 - L0 ausgegeben werden. Die Initialisierung des Ports C soll als Unterprogramm (Name: PINI) formuliert werden.
Zusätzlich soll ein 8-bit-Lauflicht mit einem Takt von 10 Hz programmiert werden. Seine aktuelle Stellung soll über Port B [7:0] ausgegeben und mittels der LEDs L15 - L8 angezeigt werden. Der zeitbestimmende Programmteil sowie das Weiterschalten und Anzeigen des Lauflichts sollen als Unterprogramme (Namen: DELAY und DISPLAY) formuliert werden.

Nun soll sich der Takt verändern lassen. Der über die Schalter S7 - S4 des Experimentier-Boards eingestellte und über Port C [3:0] eingelesene Wert stellt die Lauflichtfrequenz in Hz dar, wenn er grösser als 0 ist. Der Wert 0 führt zu einem Anhalten der Anzeige (Lauflicht bleibt stehen und läuft erst weiter, wenn der Wert grösser als 0 ist). Siehe Anmerkung unten.
Als Letztes soll noch mittels der Taste T0, die am Eingang STRA des M68HC11 anzuschließen ist, die Laufrichtung von Linkslauf auf Rechtslauf umgeschaltet werden können und umgekehrt (toggle).
Anmerkung: Es gilt bekanntlich, dass die Frequenz ein Kehrwert der Zeit (Periodendauer) ist (f = 1/t). Für eine Warteschleife, wie sie in der Vorlesung behandelt wurde, muss die Frequenz in eine Periodendauer umgerechnet werden (1 Hz = 1000 ms, 2 Hz = 500 ms, 3 Hz = 333 ms, 4 Hz = 250 ms usw.). Das Umrechnen der Frequenz in die Wartezeit kann programmtechnisch auf zweierlei Weise geschehen, durch (Integer-)Division oder durch eine Tabelle. Verwenden Sie in diesem Fall die Division (IDIV-Befehl). Schematisch stellt sich die Programmierung wie folgt dar:
Die Stellung der Schalter S7 - S4 soll andauernd über Port C [3:0] eingelesen, über Port C [7:4] ausgegeben und als einstellige Sedezimalzahl angezeigt werden. Dazu ist die 7-Segment-Anzeige A3 (mit Decoder) zu verwenden. Die Initialisierung des Ports C soll als Unterprogramm (Name: PINI) formuliert werden.
Nun werden die 7-Segment-Anzeigen A1 und A2 (mit Decoder) an Port B (A1: [7:4], A2: [3:0]) angeschlossen. Es soll eine 'Digitaluhr' programmiert werden, die Sekunden und Zehntelsekunden anzeigt (Sekunden Zehner auf A1, Sekunden Einer auf A2 und Zehntelsekunden auf A3). Dazu wird, wie schon im ersten Versuch, einem Warteroutine DELAY benötigt, die hier eine Periodendauer von 100 ms hat.
Die Digitaluhr soll bei einen vorgegebenen Wert (Programmvariable) starten, bis zum Wert 00.0 herunterzählen und dann anhalten. Mittels der Taste T0, die am Eingang STRA des M68HC11 anzuschließen ist, kann der Zähler mit dem voreingestellten Anfangswert gestartet oder gestoppt werden.
Über die Schalter S7 - S4 an Port C [3:0] soll die Startzeit des Zählers aus einer Tabelle gewählt werden, wobei in der Tabelle nur die Sekunden gespeichert werden, die Zehntensekunden starten immer mit 0. Die Tabelle besitzt somit 16 Einträge. Die in der Tabelle einzutragenden Zeiten sind frei wählbar.
Zum Einstieg soll das ASCII-Zeichen 'R' mit einer Wiederholfrequenz von etwa 5 Hz andauernd auf das Terminalfenster des Hyperterminal-Programms ausgegeben werden. Die Initialisierung des SCI ist als Unterprogramm (Name: SINIT) zu formulieren. Das Senden des Zeiches soll durch ein Unterprogramm namens CHOU erfolgen, das das im Akku A übergebene Zeichen (bei freier Schnittstelle) sendet.
Ein vorbereiteter Text (nullterminierter ASCII-String) ist nun mittels des neu zu schreibenden Unterprogramms STOU dauernd auf das Terminalfenster auszugeben. Register X enthält die Adresse des ersten Zeichens des Textes. Das Unterprogramm STOU gibt die ab (X) stehenden ASCII-Zeichen unter Verwendung des Unterprogramms CHOU aus, bis das Textendezeichen (\0) gefunden wird, das selbst nicht mit ausgegeben wird. Stattdessen werden die Steuerzeichen CR (Carriage Return) und LF (Line Feed) ausgegeben.
Ein über die Tastatur eingegebenes Zeichen ist mittels des Unterprogramms CHIN einzulesen und mittels des Unterprogramms CHOU als Echo auszugeben (Endlos-Schleife). Das Unterprogramm CHIN übergibt das gelesene Zeichen im Akku A.
Nun soll statt eines einzelnen Zeichens ein String über die Tastatur eingegeben, mittels des Unterprogramms STIN eingelesen und im Speicher abgelegt werden. STIN verwendet seinerseits CHIN, um ein Zeichen zu lesen. Zur Kontrolle wird der String mithilfe des Unterprogramms STOU wieder ausgegeben (Endlos-Schleife). Das Unterprogramm STIN soll folgende Eigenschaften besitzen:
Mittels STIN soll schließlich eine Zeichenkette eingelesen und mit einem im Programm abgelegten, konstanten String zeichenweise verglichen werden (z. B. als Passwortabfrage). Das Ergebnis des Vergleichs soll über Port B [3:0] ausgegeben und mittels der 7-Segment-Anzeige A1 (mit Decoder) dargestellt werden:
Ein 2-stelliger Sedezimalzähler ist mit einer Frequenz von 10 Hz zu betreiben. Seine aktuelle Stellung soll über Port C [7:0] ausgegeben und mittels der 7-Segment-Anzeigen A1 und A2 (mit Decoder) dargestellt werden. Der zeitbestimmende Programmteil soll als Unterprogramm (D100) unter Verwendung des Registers Y formuliert werden. Orientieren Sie sich an den Programmen aus Versuch 1 und 2.
Modifizieren Sie das Programm nun so, dass beim Starten des Programms der Text "M68HC11 gestartet" auf das Terminalfenster ausgegeben wird. Verwenden Sie dazu die beim Versuch 3 entwickelten Unterprogramme zur Initialisierung der SCI, sowie zur Zeichen- und Stringausgabe (CHOU und STOU).
Zusätzlich sind nun bedingte Unterbrechungen zu bearbeiten. Mittels der Tasten T0 und T1, die an den Eingängen STRA und PA7 des M68HC11 anzuschließen sind, können bedingte Unterbrechungen ausgelöst werden. Als Folge darauf sollen vom Hauptprogramm aus die unten beschriebenen Aktionen erfolgen.
Die Unterprogramme zur Unterbrechungsbearbeitung sind möglichst kurz zu halten. Zur Signalisierung von der Unterbrechungsbearbeitung zum Hauptprogramm sollen die Bits 0 und 1 einer Variablen DFLG (display flag) verwendet werden. Die zum Starten der Unterbrechungsbearbeitungen nötigen Vektoren nicht vergessen:
org $ffda
dc.w pirq ; pulse accu input (PA7)
org $fff2
dc.w sirq ; IRQ/STRA
org $fffe
dc.w main ; reset
Die beiden Unterprogramme hx2a und hx4a können Sie von dieser Angabe per Cut-and-Paste übernehmen. Dabei ist zu beachten, dass hx2a und hx4a den entstehenden String nach fallenden Adressen hin aufbauen und dass damit die Übergabeparameter entsprechend gewählt werden müssen. Sehen Sie sich dazu auch den Quelltext zu den Unterprogrammen am Ende dieses Dokuments an.
hx4a psha ; Akku A auf dem Stack ablegen
bsr hx2a ; Akku B umwandeln (Stelle 3 und 4)
pulb ; Akku A vom Stack holen, in Akku B ablegen
; Nun einfach in hx2a fallen und Akku B
; umwandeln (Stelle 1 und 2)
hx2a pshb ; Akku B auf dem Stack sichern
bsr hx1a ; Bits 0-3 von Akku B umwandeln
pulb ; Original-Akku B wieder holen
lsrb ; viermal schieben (Bits 4-7 --> 0-3)
lsrb
lsrb ; und nun die obere Haelfte umwandeln
lsrb ; indem einfach in hx1a gefallen wird
; Nun wird die eigentliche Arbeit gemacht:
hx1a andb #$0F ; die oberen 4 Bits ausmaskieren
addb #48 ; ASCII-Wert von "0" addieren
cmpb #57 ; groesser als "9"?
bls hx1b ; nein, dann speichern
addb #7 ; sonst die Distanz zwischen "9" und "a" addieren
hx1b stab 0,y ; im Speicher ablegen, auf den Y zeigt
dey ; Y zeigt jetzt auf die Stelle davor
rts ; und weg
Beispielaufruf:
ldd #$AFFE ; Hexzahl in Akku D laden
ldy #PUFFER+3 ; Position auf letzte Stelle im Puffer
; der Puffer muss im Datenbereich reserviert sein
bsr hx4a ; do it!
ldy #PUFFER ; y --> Pufferanfang
bsr STOU ; z.B. seriell ausgeben