Mikrocomputertechnik


Prof. Jürgen Plate

Praktikum Mikrocomputer

Versuch 1: Parallel-Ports, Unterprogramme, Zeitverzögerungen

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:

  1. Entwurf einer Warteschleife für 1 Hz = 1000 ms mit einem möglichst großen Startwert I des Schleifenzählers.
  2. Einlesen der Schalterstellung und Expandieren des Wertes auf eine 16-Bit-Variable K.
  3. Division von J = I/K. J ist nun der aktuelle Startwert für die Zählschleife.

Versuch 2: Parallel-Ports, 7-Segmentanzeige, Tabellenzugriff

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 Flußdiagramm und programmieren Sie dann danach.

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.

Versuch 3: Serielle Schnittstelle, ASCII-Zeichenketten

Bei diesem Versuch soll unter Verwendung des SCI (Asynchronous Serial Communications Interface) des M68HC11 Datenverkehr zwischen Prozessor M68HC11 und PC als Terminal 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.

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:

  1. STIN echot die mittels CHIN eingelesenen Zeichen und legt sie im Speicher ab. Die Adresse des Eingabepuffers wird im Indexregister X übergeben.
  2. Das ASCII-Zeichen CR beendet die Eingabe, es wird ohne Echo als Nullbyte abgelegt.
  3. STIN wird durch die Ausgabe von CR und LF abgeschlossen.

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:

  1. Stimmen beide Zeichenketten überein, wird eine "1" ausgegeben.
  2. Sind die Zeichenketten unterschiedlich, wird ein "F" ausgegeben (für "falsch").
  3. Erfolgt dreimal hintereinander eine falsche Eingabe, wird "E" ausgegeben (für "Error") und keine Eingabe mehr angenommen.

Versuch 4: Zähler, bedingte Unterbrechungen

Bei diesem Versuch sollen ein einfacher Zähler betrieben und verschiedene bedingte Unterbrechungen aktiviert und bearbeitet werden. Geeignete Programmteile sind als Unterprogramm zu formulieren. Zeichnen Sie immer zuerst ein Flussdiagramm und programmieren Sie dann danach.

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.

Anhang: Binär zu ASCII-Decodierung (hx4a)

Diese Unterprogramme werden beim vierten Praktikumstermin benötigt. Im Speicher liegen die Werte bekanntermaßen binär vor. Um einen Speicherinhalt oder eine Adresse auf der seriellen Schnittstelle (Terminal) oder einem LC-Display ausgeben zu können, müsen die Werte als ASCII-Zeichen dargestellt werden.
Die folgenden vier miteinander verbundenen Unterprogramme wandeln einen 16-Bit-Wert, einen 8-Bit-Wert oder einen 4-Bit-Wert in eine Hexadezimalzahl in ASCII-Darstellung um (4, 2, oder 1 Stelle):
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



[ Praktikumsanleitung ] [ Skript ]

Copyright © FH München, FB 04, Prof. Jürgen Plate
Letzte Aktualisierung: 20. Feb 2011, 16:49:01