5.2.13
12/18/17
Last Modified 06/12/15 by Walter Tasin
MC_Praktikum Reload Page

Praktikum Mikrocomputer

W. Tasin, M.Sc.

Hier finden Sie die Verweise auf Unterlagen für die Praktikumsvorbereitung und -durchführung zur Lehrveranstaltung Mikrocomputer.
Sie können rechts oben am Datum erkennen, ob eine Aktualisierung der Seite stattfand.


Hinweis zur Verwendung der hier veröffentlichten Unterlagen
Die hier veröffentlichten Unterlagen sind in erster Linie als vorlesungsbegleitende Dienstleistung zu verstehen.
Der Inhalt der Skripten darf für nichtkommerzielle Zwecke (dies schließt auch die kostenlosen Weitergabe innerhalb kommerzieller Unternehmen ein) frei verwendet werden, sofern der Inhalt in unveränderter Form und vollständig verwendet wird.
Siehe auch Hinweise auf Netzmafia.




Praktikum

Bei dem Praktikum Mikrocomputer handelt es sich um eine Zulassungsvoraussetzungen der schriftliche Prüfung Mikrocomputertechnik (am Ende des 4. Semester).
In diesem Praktikum müssen 4 Versuche mit Erfolg abgelegt werden, damit diese Zulassungsvoraussetzung erfüllt ist.



Softwaresammlung zum MC68HC11

Auf folgendem Link finden Sie eine Softwaresammlung für Windows, um Assemblerprogramme zu erstellen
und die Funktionsfähigkeit auf Ihrem PC zu testen.

Softwarepaket HC11-IDE

Weitere Software finden Sie unter:

http://www.netzmafia.de/software/mc/index.html

Zur Erstellung von Programmablaufplänen empfiehlt sich die Verwendung des
PAPDesigners:

http://friedrich-folkmann.de/papdesigner/Hauptseite.html
Weitere Hinweise zum Praktikum finden Sie unter:
http://lsw.ee.hm.edu/~tasin/praktikum_mc/Hinweise_zum_Praktikum_Mikrocomputer.pdf


Versuchsbeschreibungen



Versuch 1 - Parallel-Ports, Unterprogramme, Zeitverzögerung, 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 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 L7 - L4 ausgegeben werden. Die Initialisierung des Ports C soll als Unterprogramm (Name: pInit) 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. Dabei soll zuerst die LED L8 eingeschaltet werden, im zweiten Schritt zusätzlich LED L9, dann zusätzlich LED L10 usw. bis alle acht LEDs leuchten. Nun wird im folgenden Schritt LED L8 ausgeschaltet, dann L9 usw. bis alle LEDs wieder dunkel sind - worauf das Spiel von vorne beginnt.
Tipp: Der Effekt ist ganz einfach zu erreichen, wenn der aktuelle 8-Bit-Wert, der die LEDs repräsentiert, immer nach links geschoben wird und in der ersten Phase zusätzlich das niederwertige Bit auf 1 gesetzt wird. In der zweiten Phase ist nichts zu tun, da sowieso eine 0 nachgeschoben wird.

lauflicht2.gif

Der zeitbestimmende Programmteil sowie das Weiterschalten und Anzeigen des Lauflichts sollen jeweils als Unterprogramme (Namen: delay und display) formuliert werden.

Nun wird das Programm erweitert: Es 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 (Pull-Up-Widerstände nicht vergessen) 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, das Lauflicht auch bei Frequenzen größer 0 angehalten bzw. gestartet werden (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, State-Machine

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 Initialisierung der Ports sowie alle anderen Initialisierungen und die Vorbelegung von Variablen soll als Unterprogramm (Name: init) formuliert werden.

Wir wollen mit unserem System eine Toaster steuern, dessen Funktionen hier leider nur durch LEDs repräsentiert werden. Der Toastvorgang läuft folgendermaßen ab:

  • Mittels der Taste T0, die am Eingang PA7 des M68HC11 anzuschließen ist, wird der Toastvorgang gestartet und die Toastscheibe ins Gerät eingezogen, was durch das Aufleuchten von LED L8 für die Dauer von 0,5 Sekunden angezeigt wird.
  • Danach beginnt das Rösten der Toastscheibe, was durch Aufleuchten von LED L9 signalisiert wird. Gleichzeitig wird die Röstdauer auf 15 Sekunden initialisiert und noch anstehende Tastenanforderungen werden gelöscht.
  • Während des Röstvorgangs wird die restliche verbleibende Zeit dezimal über die 7-Segment-Anzeigen A1 und A2 (mit Decoder) angezeigt an Port C (A1: [7:4], A2: [3:0]) angeschlossen. Es soll also ein Count-Down programmiert werden, der die Sekunden anzeigt (Sekunden Zehner auf A1, Sekunden Einer auf A2).
  • Mittels der Taste T1, die am Eingang STRA des M68HC11 anzuschließen ist, kann der Röstvorgang einmalig um 5 Sekunden verlängert werden.
  • Ist die Zeit abgelaufen, erlischt die LED L9 (die 7-Segment-Anzeige bleibt auf "00" stehen) und der Toast wird ausgeworfen, was wieder durch das Aufleuchten von LED L8 für die Dauer von 0,5 Sekunden angezeigt wird.
  • Wird während der Röstung die Taste T0 betätigt, so bricht der Röstvorgang vorzeitig ab, die 7_Segmentanzeige wird auf "00" gestellt und der Toast wird ausgeworfen.

Für alle Abläufe wird, wie schon im ersten Versuch, einem Warteroutine delay benötigt, die hier eine Periodendauer von 0,5 s hat (für den Test kann man diese Zeit ja verkürzen). Das bedeutet auch, dass alle interaktiven Aktionen mindestens 0,5 s andauern müssen.

Hinweis zur Programmierung

Eine sehr häufig anzutreffende Methode derartige Abläufe vernünftig zu programmieren, ist die sogenannte State-Machine (Zustandsfolge-Maschine, Automat). Das Prinzip kennen Sie hinreichend aus der Vorlesung "Digitale Schaltwerke", der Unterschied ist hier die Realisierung als Software. Die Alarmanlage kennt fünf Zustände, die als Konstanten definiert werden:

STANDBY    EQU 1  ; Ruhezustand
START      EQU 2  ; Toast einziehen
ROAST      EQU 3  ; Toast rösten
EXT_ROAST  EQU 4  ; Röstzeit erweitern (Nachrösten)
FINI       EQU 5  ; Toast auswerfen

Die State-Machine gestaltet sich folgendermassen:

  • In einer Endlosschleife wird der aktuelle Zustand gelesen und für jeden Zustand:
    • für den jeweiligen Zustand erforderlichen Aktionen ausgeführt,
    • abhägig vom aktuellen Zustand und dem Wert von Taste T0 der neue Zustand gesetzt (bzw. der aktuelle Zustand beibehalten) -> die globale Zustandsvariable erhält einen der o. a. Zustandswerte.
  • Der "Takt" der State-Machine beträgt in unserem Fall 2 Hz (wegen der delay-Routine von 0,5 Sekunden). Aus diesem Takt wird alles andere abgeleitet.

Die folgende Abbildung zeigt das grundlegende Zustandsfolge-Diagramm. Notieren Sie alle Aktionen, die für jeden Zustand auszuführen sind und eventuell benötigte Variablen. Setzen Sie diese Informationen dann in ein Programm um. Es kann bei umfangreicheren Aufgaben durchaus sinnvoll sein, alle Aktionen eines jeden Zustands in einem Unterprogramm zusammenzufassen. So können Die Aktions-Unterprogramme unabhängig von der eigentlichen State-Machine entwickelt und getestet werden. Das folgende Bild zeigt nur die Zustandsübergänge bzw. die Bedingungen, nicht jedoch die Aktionen (z. B. das Runterzählen).

state-machine.jpg

Grundsätzlich folgt das Programm dem Schema aus der Vorlesung, das hier nochmals kurz skizziert wird. Übernehmen Sie das unten stehende Schema in Ihr Hauptprogramm und formulieren Sie die notwendigen Unterprogramme für die einzelnen Aktionen.

   ...
   Definitionen, Initialisierung
   ...
 
; mainloop = statemachine
loop  jsr       display    ; ggf. Anzeige der Restzeit
      jsr       delay      ; Warteschleife
                           ; ggf. weitere allgemeine Aktionen
 
      ldaa      state      ; aktueller Status      
S0    cmpa      #STANDBY   ; Idle-Zustand, waten auf T0?
      bne       S1         ; nein, weiter
      bsr       DoStandby  ; Aktion und Statuswechsel ausfuehren
      bra       loop       
 
S1    cmpa      #WAIT      ; warten bis T0 losgelassen?
      bne       S2         ; nein, weiter
      bsr       DoWait     ; Aktion und Statuswechsel ausfuehren
      bra       loop
 
S2    cmpa      #ROAST     ; Roesten?
      bne       S3         ; nein, weiter
      bsr       DoRoast    ; Aktion und Statuswechsel ausfuehren
      bra       loop
 
S3    cmpa      #EXT_ROAST  ; Extra braun?
      bne       S4         ; nein, zu loop (keine Fehlerbehandlung)
      bsr       DoExtend   ; Aktion und Statuswechsel ausfuehren
      bra       loop
 
S4    cmpa      #FINI      ; Auswerfen?
      bne       loop       ; Ops! Unbekannter Zustand!
      bsr       DoEject    ; Aktion und Statuswechsel ausfuehren
      bra       loop



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. Als String-Terminator dient wie bei C das Nullbyte ($00). Geeignete Programmteile sind als Unterprogramm zu formulieren. Zeichnen Sie immer zuerst ein Flussdiagramm und programmieren Sie dann danach.


Wichtig: Zum Terminalbetrieb ist nach dem Terminalbetrieb der Schalter "PC-MAN" am Praktikumsrechner in Stellung MAN zu bringen. Zum Laden des Programms muss er dann wieder auf PC gestellt werden. Entsprechend muss beim Hyperterminal zum Programm-Download "aufgelegt" (Telefon-Icon in der oberen Werkzeugleiste) und zum Betrieb wieder "abgehoben" werden.


Aufgabenstellung

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 chOut erfolgen, das das im Akku A übergebene Zeichen (bei freier Schnittstelle) sendet.

Als Nächstes ist ein vorbereiteter Text (nullterminierter ASCII-String) mittels des neu zu schreibenden Unterprogramms strOut dauernd auf das Terminalfenster auszugeben. Register X enthält die Adresse des ersten Zeichens des Textes. Das Unterprogramm strOut gibt die ab (X) stehenden ASCII-Zeichen unter Verwendung des Unterprogramms chOut aus, bis das Textendezeichen ('\0') gefunden wird, das selbst nicht mit ausgegeben wird. Stattdessen werden die Steuerzeichen CR (Carriage Return) und LF (Line Feed) mittels des Unterprogramms outCRLF ausgegeben.

Ein über die Tastatur eingegebenes Zeichen ist mittels des Unterprogramms chIn einzulesen und mittels des Unterprogramms chOut 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 strIn eingelesen und im Speicher abgelegt werden. strIn verwendet seinerseits chIn, um ein Zeichen zu lesen. Zur Kontrolle wird der String mithilfe des Unterprogramms strOut wieder ausgegeben (Endlos-Schleife). Das Unterprogramm strIn soll folgende Eigenschaften besitzen:

  • strIn echot die mittels chIn eingelesenen Zeichen und legt sie im Speicher ab. Die Adresse des Eingabepuffers wird im Indexregister X übergeben.
  • Nicht darstellbare Zeichen (alle ASCII-Zeichen < " ") werden bei der Eingabe ignoriert.
  • Das ASCII-Zeichen CR beendet die Eingabe, es wird ohne Echo als Nullbyte abgelegt.
  • strIn wird durch die Ausgabe von CR und LF abgeschlossen (Unterprogramm outCRLF).

Das folgende Programm läuft als Schleife ab. Zuerst wird mittels strOut der Text "Passwort: " ausgegeben (ohne CRLF). Mit dem Unterprogramm strIn soll nun eine Zeichenkette eingelesen und mit einem im Programm abgelegten, konstanten String zeichenweise verglichen werden. (typische Passwortabfrage). Das Ergebnis des Vergleichs soll über Port B [6:0] ausgegeben und mittels der 7-Segment-Anzeige A5 (ohne Decoder) dargestellt werden:

  • Sind die Zeichenketten unterschiedlich, wird das Zeichenmuster 0 (siehe Tabelle unten) ausgegeben (für "falsch"). Gleichzeitig wird ein Fehlerzähler inkrementiert.
  • Stimmen beide Zeichenketten überein, wird eine das Zeichenmuster 1 ausgegeben. Der Fehlerzähler wird in diesem Fall zurückgesetzt.
  • Erfolgt dreimal hintereinander eine falsche Eingabe (Fehlerzähler = = 3), wird das Zeichenmuster 2 ausgegeben, das im Rhythmus von 2 Hz im Wechsel mit Zeichenmuster 0 blinkt. In diesem Fall wird auch keine weitere Eingabe mehr angenommen und der Zustand kann nur mit der Reset-Taste beendet werden.

Die Zeichenmuster werden, wie in der Vorlesung gezeigt, in einer Tabelle mit drei Elementen abgelegt. Zur Umcodierung der Werte 0 bis 2 schreiben Sie ein Unterprogramm recode, das den Eingangswert in Register B erwartet, diesen prüft bzw. normiert, und den Anzeigecode ebenfalls in Register B zurückgibt.

Zeichenmuster 0 Zeichenmuster 1 Zeichenmuster 2
pmc-z0.gif pmc-z1.gif pmc-z2.gif

Programmieren Sie für den Vergleich ein eigenes Unterprogramm, dem die Anfangsadressen der beiden zu vergleichenden Zeichenketten in den Registern X und Y übergeben werden.

Modifizieren Sie die Eingaberoutine strIn so, dass nicht das eingegebene Zeichen, sondern stattdessen ein '*' geechot wird (es genügt in der Regel, nur einen Assemblerbefehl an der richtigen Stelle einzufügen).



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.

Aufgabenstellung

Ein 2-stelliger Sedezimalzähler ist mit einer Frequenz von etwa 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 (delay100) unter Verwendung des Registers Y formuliert werden. Orientieren Sie sich an den Programmen aus den Versuchen 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 (chOut und strOut).

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 (Ohne Pullup-Widerstände!), 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 zwei Flag-Variablen PFLAG (PA7) und SFLAG (STRA) 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

Beim Auftreten einer Unterbrechung durch T1 an PA7 soll der jeweilige Befehlszählerstand des unterbrochenen Programms als 4-stellige Hexzahl auf das Terminalfenster ausgegeben werden ("PC=XXXX"). Verwenden Sie dazu unter anderem das Unterprogramm hx4a (siehe unten).
Von der Interrupt-Serviceroutine wird nur der Wert des Befehlszählers* in der 16-Bit-Variablen PCSTAT ans Hauptprogramm übergeben. Die Tatsache, dass ein Interrupt auftrat, wird in einer Flag-Variablen namens PFLAG signalisiert.
Die Umwandlung Binär -> Hexziffernstring sowie die Ausgabe erfolgen im Haptprogramm, das auch PFLAG wieder zurücksetzt.

Beim Auftreten einer Unterbrechung durch T0 an STRA soll jeweils nach dem 3. Impuls am Interrupteingang (also nach dreimaligem Tastendruck) der Zähler gestoppt und erst nach weiteren 3 Tastenbetätigungen wieder weiterlaufen. Dies soll sich periodisch wiederholen. Bearbeiten Sie das Zählen der Tastenbetätigungen innerhalb der Interrupt-Serviceroutine und signalisieren Sie die Start/Stopp-Information über eine Flag-Variable namens SFLAG. Im Hauptprogramm wird anhand dieser Variablen entschieden, ob der Zähler läuft oder steht.

Das Unterprogramme hx4a können Sie aus der Angabe "Hinweise zum Praktikum" per Cut-and-Paste übernehmen. Dabei ist zu beachten, dass hx4a den entstehenden String nach fallenden Adressen hin aufbaut (also von hinten) und dass damit die Übergabeparameter entsprechend gewählt werden müssen. Achten Sie darauf, dass auch der durch hx4a erzeugte String mit einem Nullbyte abgeschlossen werden muss. Sehen Sie sich dazu auch den Quelltext zu den Unterprogrammen am Ende dieses Dokuments an.

  • Frage: Wo befindet sich der Stand des Program Counters, wenn die Interrupt Service Routine läuft?
    Antwort: Auf dem Stack.
  • Frage: Wie komme ich da dran?
    Antwort: In der Befehlsreferenz nachsehen: Stacking-Order. Dort sieht man, dass der Stackpointer auf das erste freie Byte zeigt, dann folgen:
SP ->
CC
B
A
X hi
X lo
Y hi
Y lo
PC hi
PC lo
Der PC liegt also 8 Bytes höher. Da der SP nicht zum Adressieren verwendet werden kann, nehmen wir die Befehle TSX (Transfer S nach X), TSY (Transfer S nach Y) oder den Befehl STS (Store Stackpointer). TSX und TSY erhöhen den Wert schon um 1, damit X/Y gleich auf das CC-Register zeigen. Also liegt der PC da bei X+7 bzw. Y+7.



Links

Terminplan Mikrocomputer
Unterlagen Mikrocomputer
Zur Hauptseite