Einsendeaufgaben zur Kurseinheit 5
Aufgabe 5-1: (25 Punkte)
a) (15 Punkte, Lösungsdatei: 1A_EA.ASM)
Schreiben Sie ein Programm, welches die Hilfsroutine DLY1MS benutzt, um die Verzögerung zu messen, nach der der (fast) gleichzeitig gestartete Zähler #3 einen Interrupt erzeugt. Sie nutzen dabei die Tatsache aus, daß das Register Y während
des Ablaufs der Hilfsroutine jede Millisekunde dekrementiert wird. Daher kann in einer Interruptroutine, die die Routine DLY1MS unterbricht, das Register Y abgefragt werden.
Im einzelnen soll das Programm,
- die Anzeige löschen,
- die Kennung "Ab" für "Abbruch" in den Anzeigestellen S7, S6 anzeigen und in den Anzeigestellen S5..S2 den Wert einlesen, mit dem das Auffangregister von Zähler #3 programmiert werden soll,
- die Kennung "dE" für "Delay" in den Anzeigestellen S7, S6 anzeigen und in den Anzeigestellen S5..S2 den Wert einlesen, der der Hilfsroutine DLY1MS als Verzögerungsdauer (in ms) übergeben wird,
- die Anzeige löschen,
- den Interruptvektor von Zähler #3 setzen,
- den Zähler #3 und dessen Auffangregister programmieren,
- den Zähler #3 aktivieren und dann die Hilfsroutine DLY1MS starten.
Falls die Hilfsroutine nicht durch einen Interrupt unterbrochen, sondern normal beendet wird, soll das Programm:
- den Interrupt von Zähler #3 sperren,
- in der Anzeigestelle S0 die Kennung "F" für "Fertig" ausgeben,
- in einer Endlosschleife warten.
Falls der Interrupt vom Zähler #3 ausgelöst wird, soll die Interruptroutine:
- die Kennung "b" für "Break" in S0 ausgeben,
- den Inhalt des Registers Y in S5..S2 ausgeben,
- in einer Endlosschleife warten.
b) (5 Punkte)
Ändern Sie Ihr Programm aus a) so, daß
in der Interruptroutine nicht die noch zu wartenden Millisekunden ausgegeben werden, sondern die schon verstrichenen.
c) (5 Punkte)
Geben Sie die folgenden Werte für den Abbruch "Ab" und das Delay "dE" in Ihr Programm ein und notieren Sie die Ausgaben des Registers Y und die verstrichenen Millisekunden.
Berechnen Sie anhand der Programmierung des Zählers und des Auffangregisters die Zyklusdauer, nach der tatsächlich ein Interrupt ausgelöst wird.
| Ab |
dE |
Y (aus Teil a) |
Verzögerung (aus Teil b) |
Zyklusdauer |
| $FFFF |
$FFFF |
| | |
| $8000 |
$FFFF |
| | |
| $FFF |
$8000 |
| | |
| $8000 |
$8000 |
| | |
| $FFFF |
$1000 |
| | |
| $8000 |
$1000 |
| | |
| $1000 |
$0100 |
| | |
| $8000 |
$0100 |
| | |
Aufgabe 5-2: (25 Punkte)
a) (10 Punkte, Lösungsdatei: 2A_ML.ASM)
Schreiben Sie ein Programm, welches interruptgesteuert Zeichen von der seriellen Schnittstelle empfängt und in den Anzeigestellen
S1, S0 ausgibt. In der Anzeigestelle S7 soll ein "E" ausgegeben werden, falls der Schnittstellenbaustein einen Empfangsfehler meldet.
Im einzelnen soll das Programm,
- die Anzeige löschen,
- den Interruptvektor für die V.24-Schnittstelle setzen und die V.24-Schnittstelle initialisieren,
- in einer Endlosschleife verweilen.
Die Interruptroutine soll im einzelnen
- prüfen, ob das Empfangen eines Zeichens der Grund für den Interrupt war,
- das Zeichen einlesen und in den Anzeigestellen S1, S0 in hexadezimaler Form ausgeben,
- die drei Fehlerbits des Statusregisters (im Baustein R6551) prüfen und in der Anzeigestelle S7 bei einem Übertragungsfehler ein "E" anzeigen und bei fehlerfreier Übertragung die Anzeigestelle S7 löschen (, um dadurch ein evtl. angezeigtes
"E" des zuletzt empfangenen Zeichens zu beseitigen).
Hinweise:
- Um Zeichen vom Terminalprogramm korrekt zu empfangen, verwenden Sie die Parameter 1200 baud, 8 Bits pro Zeichen, ein Stopbit, Parität konstant 1 (bzw. zwei Stopbits und keine Parität). Um Empfangsfehler zu simulieren, programmieren Sie die Schnittstelle z.B. mit gerader oder ungerader Parität.
- Sie können davon ausgehen, daß während der Abarbeitung der Interruptroutine kein weiterer Interrupt auftritt. Deswegen ist es möglich, in der Interruptroutine auch die Auswertung und Ausgabe der empfangenen Daten zu erledigen. Normalerweise wird in einer Interruptroutine nur ein Puffer mit den empfangenen Daten gefüllt und das Hauptprogramm kümmert sich um die Auswertung. Bis ca. 4800 baud haben Sie jedoch auch bei "ungeschickter" Programmierung der Interruptroutine zwischen zwei Zeichen genügend
Zeit, um alles zu erledigen.
b) (10 Punkte, Lösungsdatei: 2B_ML.ASM)
Erweitern Sie Ihr Programm aus a) so, daß
viermal pro Sekunde in den Anzeigestellen S5..S2 die "CPS-Rate"
(Zeichen pro Sekunde) des Empfangsvorgangs dargestellt wird. Benutzen
Sie dazu ein Byte, in welchem Sie die empfangenen Zeichen mitzählen.
Im einzelnen soll das Programm statt der Endlosschleife aus a)
- eine Viertelsekunde warten (Hilfsroutine DLY1MS),
- den Zeichenzähler laden und auf Null setzen,
- die CPS-Rate errechnen und in den Anzeigestellen
S5..S2 darstellen,
- mit 1) fortfahren.
Die Interruptroutine soll zusätzlich zu a) den
Zeichenzähler für jedes empfangene Zeichen inkrementieren.
Hinweise:
- Benutzen Sie zum Testen verschiedene Baudraten,
z.B. 300, 1200, 2400 und 9600 Baud.
- Im Simulatorprogramm können Sie eine V.24-Aufzeichnung von der Festplatte "einspielen", welches immer automatisch mit der aktuellen Baudrate abgespielt wird.
c) (5 Punkte)
Berechnen Sie anhand der Übertragungsparameter die theoretischen Werte, die Ihre CPS-Anzeige bei 300, 1200, 1400 und 9600 Baud liefern müßte.
Vergleichen Sie die Werte mit denen, die Sie mit dem Praktikumsrechner und dem Simulatorprogramm erzielt haben. Beantworten Sie folgende Fragen:
- Warum weichen die am Praktikumsrechner erzielten CPS-Werte mit steigender Baudrate immer stärker von den theoretischen Werten ab?
- Warum funktioniert die Anzeige bei 19200 baud völlig falsch?
- Was könnten die abweichenden Anzeigen im Simulatorprogramm bedeuten?
Aufgabe 5-3: (25 Punkte)
a) (5 Punkte; Vorlagedatei: 3_VORL.ASM; Lösungsdatei: 3_EA.ASM)
Die Vorlagedatei entspricht der Lösung zur Praktischen Übung P5.2-3. Erweitern Sie das Programm so, daß in der Interruptroutine ein 16-bit-Zähler erhöht und in den Anzeigestellen S7..S4 ausgegeben wird. Dadurch kann beobachtet werden, wie oft der Timer einen Interrupt auslöst. Bei jeder
Änderung des Delay-Wertes soll der Zähler zurückgesetzt werden.
Hinweise:
- Die Zeilen 29 und 30 der in der Kurseinheit abgedruckten Lösung entfallen.
- Die Zeile 45 der in der Kurseinheit abgedruckten Lösung entfällt. Damit das Monitorprogramm feststellen kann, welcher Timer einen Interrupt ausgelöst hat, muß schon in der Bearbeitungsroutine des NMI-Interrupts das Statusregister des Timers ausgelesen werden. Anhand des Wertes wird entschieden, ob ein Timerinterrupt vorliegt und welcher Interruptvektor für die Unterbrechungsroutine zu benutzen ist. Falls Ihre Routine aufgerufen wird, können Sie also sicher sein, daß ein
Interrupt vom Timer vorliegt und daß das I-Flag des Bausteins zurückgesetzt wurde.
b) (5 Punkte)
Füllen Sie die folgende Tabelle mit den ermittelten hexadezimalen und den daraus errechneten dezimalen Werten aus.
| Parameter für DLY1MS |
Verzögerung beim Frequenzvergleich ($CA) |
Verzögerung beim Pulsbreitenvergleich ($DA) |
Verzögerung beim Frequenzvergleich mit 1/8 Takt ($CB) |
| $01 |
/ | / |
/ |
| $02 |
/ | / | / |
| $03 |
/ | / | / |
| $04 |
/ | / | / |
| $10 |
/ | / | / |
| $20 |
/ | / |
/ |
Die Werte des Frequenzvergleich werden etwa doppelt so hoch sein wie die des Pulsbreitenvergleichs. Die Werte in der letzten Spalte werden etwa um den Faktor 8 niedriger sein als die in der ersten Spalte; bitte geben Sie dort zusätzlich das Ergebnis mit 8 multipliziert an.
c) (5 Punkte)
Beantworten Sie folgende Fragen:
- Woraus resultiert der pro Spalte konstante Fehler der Zeitmessung?
- Der Fehler beim Pulsbreitenvergleich kann "auf den Takt genau" erklärt werden. Wie lautet diese Erklärung?
- Wieso ist der Fehler in den beiden Spalten des Frequenzvergleiches unterschiedlich, auch nach Multiplikation der letzten Spalte mit 8?
- Wenn Sie während des Frequenzvergleiches eine Taste außer "S" drücken, ändert sich die angezeigte Verzögerung. Woran liegt das? Wieso wird bei jeder Taste eine andere Verzögerungsveränderung verursacht?
Hinweis:
- In der Monitorversion 7A benötigt die Hilfsroutine DLY1MS einen Overhead von 26 Takten = 0,026ms.
d) (10 Punkte; Lösungsdatei: 3D_EA.ASM)
Ändern Sie das Programm aus a) so, daß es die Anzahl der Impulse pro Sekunde anzeigt. Programmieren Sie dazu den Zeitgeberbaustein so, daß er alle 250ms einen Interrupt erzeugt. Im Hauptprogramm ist nach jedem Impuls ein Zähler zu erhöhen, dessen Stand (umgerechnet auf Impulse pro Sekunde) in der Interruptroutine ausgegeben werden soll.
Das Programm soll im einzelnen:
- den Interruptvektor für den Timer #3 auf die eigene Routine setzen,
- den Timer #3 initialisieren mit: Output enable, Interrupt enable, zyklischer Zählbetrieb, 16-bit-Modus, interner Takt, 1/8 Taktfrequenz,
- einen Verzögerungswert in den Anzeigestellen S7..S4 abfragen und währenddessen den Timer stoppen,
- in einer Schleife einen 8-bit-Zähler erhöhen, die in 3) eingegebene Zahl von Millisekunden warten (Hilfsroutine DLY1MS) und zu Punkt 3) springen, falls die Taste "S" gedrückt ist.
Die Interruptroutine soll im einzelnen:
- den Zähler laden, löschen, mit 4 multiplizieren und in den Anzeigestellen S3..S0 ausgeben,
- den Timer rücksetzen, um den nächsten Interrupt zu erzeugen.
Aufgabe 5-4: (25 Punkte, Lösungsdatei:4_EA.ASM)
In dieser Aufgabe sollen Sie die Ergebnisse der Aufgaben 5-2 und 5-3 verbinden, um eine korrekte CPS-Anzeige zu programmieren.
a)
Erweitern Sie Ihr Programm aus Aufgabe 5-2 a) so, daß in der Interruptroutine das empfangene Zeichen nicht mehr in der Anzeige, sondern an den Parallelport ausgegeben wird.
Im einzelnen soll das Programm
- die Anzeige löschen,
- den Interruptvektor für die V.24-Schnittstelle setzen und die V.24-Schnittstelle initialisieren,
- den Port PB so programmieren, daß keine Interrupts erzeugt werden und CB1 als Eingang, CB2 und alle acht Portleitungen Pbi als Ausgang geschaltet sind,
- in einer Endlosschleife verweilen.
Die Interruptroutine soll im einzelnen:
- prüfen, ob das Empfangen eines Zeichens Grund für den Interrupt war,
- das Zeichen einlesen und an den Port PB ausgeben,
- die drei Fehlerbits des Statusregisters prüfen und in der Anzeigestelle S7 bei einem Übertragungsfehler ein "E"
anzeigen und bei fehlerfreier Übertragung die Anzeigestelle S7 löschen (um ein evtl. angezeigtes "E" des zuletzt empfangenen Zeichens zu beseitigen).
b) (7 Punkte; Lösungsdatei: 4B_EA.ASM)
Erweitern Sie Ihr Programm aus a) um das Meßverfahren aus Aufgabe 5-3 a), um die Empfangsdauer eines Zeichens zu messen. Programmieren Sie dazu die Parallelschnittstelle so, daß nach jeder Ausgabe eines Zeichens ein kurzer Strobe an CB2 erzeugt
wird. Der Zähler zur Anzahl der Interrupts soll entfallen.
Im einzelnen soll das Programm:
- die Anzeige löschen,
- den Interruptvektor für die V.24-Schnittstelle setzen und die V.24-Schnittstelle initialisieren,
- den Port PB so programmieren, daß keine Interrupts erzeugt werden und CB1 als Eingang, CB2 als Strobe-Handshake und und alle acht Portleitungen als Ausgang geschaltet sind,
- den Interruptvektor für den Timer seten und den Timer
so programmieren, daß Interrupt und Output aktiviert sind, daß ein Frequenzvergleich mit internem, nicht geteilten Takt durchgeführt wird und daß im 16-bit-Modus gearbeitet wird,
- in einer Endlosschleife verweilen.
Die Interruptroutine zum Zeichenempfang soll im einzelnen:
- prüfen, ob das Empfangen eines Zeichens der Grund für den Interrupt war,
- das Zeichen einlesen und an den Port PB ausgeben,
- die drei Fehlerbits des Statusregisters prüfen und in der Anzeigestelle S7 bei einem Übertragungsfehler ein "E"
anzeigen und bei fehlerfreier Übertragung die Anzeigestelle S7 löschen (, um ein evtl. angezeigtes "E" des zuletzt empfangenen Zeichens zu löschen).
Die Interruptroutine bei Timerinterrupts soll den Timerwert auslesen und in den Anzeigestellen S3..S0 ausgeben.
c) (3 Punkte)
Füllen Sie folgende Tabelle aus. Stellen Sie im Terminalprogramm die angegebenen Baudraten und Übertragungsformate ein, passen Sie die Baudrate im Empfangsprogramm an, und notieren Sie die Werte:
| Baudrate | Format |
angezeigter Wert |
ms pro Zeichen |
CPS-Rate |
| 1200 |
HEX | |
| |
| 300 |
RAW | |
| |
| 1200 |
RAW | |
| |
| 2400 |
RAW | |
| |
| 4800 |
SRAW | |
| |
| 9600 |
RAW | |
| |
| 19200 |
RAW | |
| |
Vergleichen Sie die Werte mit den Ergebnissen in Aufgabe 5-2b).
Hinweis:
- Sie werden feststellen, daß der angezeigte Wert in den letzten ein bis zwei Stellen nicht konstant ist. Rechnen Sie ruhig mit "00" oder "80" etc. als den letzten beiden Ziffern oder verwenden Sie den zuletzt angezeigten Wert. Entsprechend ungenau sind die beiden letzten Spalten.
d) (10 Punkte; Lösungsdatei: 4D_EA.ASM)
Erweitern Sie Ihr Programm aus a) um das Meßverfahren aus Aufgabe 5-3 d). Zählen Sie also während des Zeichenempfangs einen Zähler hoch. Erzeugen Sie alle 250ms einen Interrupt
und geben Sie in der Interruptroutine den Zähler umgerechnet auf Zeichen pro Sekunde aus.
Im einzelnen soll das Programm:
- die Anzeige löschen,
- den Interruptvektor für die V.24-Schnittstelle setzen und die V.24-Schnittstelle initialisieren,
- den Port PB so programmieren, daß keine Interrupts erzeugt werden und CB1 als Eingang, CB2 und alle acht Portleitungen als Ausgang geschaltet sind,
- den Interruptvektor für den Timer #3 auf die eigene Routine setzen und den Timer #3 initialisieren mit: Output enable, Interrupt enable, Zyklischer Zählbetrieb, 16-bit-Modus, interner Takt,
1/8 Taktfrequenz,
- in einer Endlosschleife verweilen.
Die Interruptroutine für den Zeichenempfang soll im einzelnen:
- prüfen, ob das Empfangen eines Zeichens der Grund für den Interrupt war,
- das Zeichen einlesen und an den Port PB ausgeben,
- einen 8-Bit-Zähler inkrementieren
- die drei Fehlerbits des Statusregisters prüfen und in der Anzeigestelle S7 bei einem Übertragungsfehler ein "E" anzeigen und bei fehlerfreier Übertragung die Anzeigestelle
S7 löschen (um ein evtl. angezeigtes "E" des zuletzt empfangenen Zeichens zu löschen).
Die Timer-Interruptroutine soll im einzelnen:
- den Zeichenzähler laden, löschen, mit 4 multiplizieren und in den Anzeigestellen S3..S0 ausgeben,
- den Timer rücksetzen, um den nächsten Interrupt zu erzeugen.