Praktikum Mikrocomputertechnik Versuch 1: Einstieg in die Assemblerprogrammierung mit dem Microcontroller XC164 IE-Labor oder DT-Labor Labor: Versuchsdurchfürhung am: Teilnehmer: Testat: Gruppe: Semester: Student 1: Student 2: Datum: Unterschrift: Bemerkungen: -1-
Praktikum Mikrocomputertechnik Versuch 1: Einstieg in die Assemblerprogrammierung mit dem Mikrocontroller XC164 1 Versuchsinhalte Vorbereitung: Aufgaben zur Vorbereitung finden Sie bei den Beschreibungen der einzelnen Versuche. Aufgabe 1: Blinken Grundlegende Konfigurationen in einem Assembler-Programm werden vermittelt. Aufgabe 2: Umgang mit dem Debugger Es wird mit verschiedenen Speicherbereichen gearbeitet. Die einzelnen Schritte werden dann mit dem Debugger analysiert. Aufgabe 3: LED Blinklicht mit Hilfe von Timern, Lauflicht Es ist Ihre Aufgabe einen Timer zu konfigurieren, damit er in bestimmten Zeitabständen einen Interrupt auslöst. Mit diesem Interrupt soll eine LED getoggelt werden. Als weiteren Schritt sollen Sie in der ISR (Interrupt Service Routine) ein Lauflicht realisieren. Ausarbeitung: Nach Beendigung des Versuches haben Sie alle Arbeiten erledigt. Sie können die Ausarbeitung direkt nach dem Praktikumstermin abgeben. Die Ausarbeitung besteht aus folgenden (für ein erfolgreiches Testat notwendigen) Komponenten: Ausgefülltes Deckblatt Das am Ende befindliche, von Ihnen ausgefüllte Fragenblatt zur Theorie Am PC erstellte Flussdiagramme, Material aus der Vorbereitung (ggf. Berechnungen, etc.) Ausdruck der Assemblerdateien zur Durchsicht. Entfernen Sie alle nicht benötigten Routinen und Unterprogramme vor dem Ausdruck. Screenshots der in Aufgabe 2 definierten Speicher-Fenster -2-
2 Grundlagen In diesem Abschnitt sollen die Grundlagen vermittelt werden, die zur Durchführung des Praktikumsversuches nötig sind. Im Anhang finden sich nützliche Tabellen um den XC164 richtig zu konfigurieren. 2.1 Allgemeines Um Anwendungen mit dem Mikrokontrollersystem XC164 erstellen zu können, benötigen sie folgende Hard- und Software, die ihnen im Industieelektonik-Labor an den entspre chenden Arbeitsplätzen zur Verfügung steht: XC164CS RapidIO Board (ist an jedem der Versuchsplätze vorhanden) Personal Computer Intronix Logicport (34 Channel Logic Analyzer) mit USB A-A-Verbindungskabel 2.2 Inbetriebnahme 2.2.1.) Erste Schritte Sowohl der DAS Server (USB Treiber zur Kommunikation mit dem xc164 Boards) als auch die Keil Entwicklungsumgebung sind auf allen PCs im Labor für industrielle Elektronik als auch in Labor für Digitaltechnik bereits installiert. -3-
2.2.2.) Die Keil Entwicklungsumgebung Da über die KEIL-Entwicklungsumgebung die Versuchsprogramme im FLASH des µcontrollers abgelegt werden, laufen eventuell vorhandene Programme Ihrer Vorgänger direkt nach dem Anschluss los. Dies brauchen Sie nicht weiter zu beachten. Sobald Sie Ihre Software das erste mal übertragen, werden die vorhandenen Programme gelöscht. a.) Aufbau des Projektes Nachdem Sie die Keil µvision3 Entwicklungsumgebung gestartet haben, öffnen Sie das Projekt PMC_Blinken, das auf der WEB-Seite des Labors zum Versuch 1 herunter gela den werden kann. Dieses Projekt beinhaltet bereits alle Settings, die zum Betrieb des xc164 in der vorhandenen Konfiguration benötigt werden. Des weiteren beinhaltet das Projekt auch einen Programm-Rumpf mit den notwendigen Rahmen. Folgende Source-Files sind in dem Projekt bereits eingebunden: START_V2.A66 Dieses File beinhaltet die Initialisierung des xc164. Darunter befinden sich u.a. die Einstellungen für die Taktfrequenz, Speicherbereiche, etc. Dieser Programmcode wird vor der Ausführung der eigenen Software ausgeführt. XC164.INC Dieses File beinhaltet alle Kürzel für die Register des µc. Bitte beachten Sie, dass die Bezeichnung verschiedener Register von den Namen des C167 abweicht. Beispielsweise haben die Register für die Steuerung der Timer andere Namen ( T3CON heißt beim xc164 nun GPT12E_T3CON ). Die genaue Registerbezeichnung können Sie den beiden Manuals für den µc entnehmen. Eine PDF-Version finden Sie auf der WEB-Seite des IE-Labors. Registerbezeichnungen bitte im Assemblerprogramm immer groß schreiben - case sensitiv. MAIN.A66 Dieses File beinhaltet den notwendigen Rumpf für Ihre eigenen Routinen. In diesem File erstellen Sie Ihr Hauptprogramm sowie alle Unterprogramme, Interrupt-Routinen und Datenbereiche. b.) Header $SEGMENTED CASE MODV2 $MODINF (43) $INCLUDE(XC164.inc) Definition des Speichermodells - Einbinden der Registernamen NCODE NCONST CGROUP DGROUP Definition Programmsettings Definition Datensettings ASSUME ASSUME DPP1 : NCONST DPP3 : SYSTEM?PR?MAIN?NC?MAIN Pagedefinition Datenspeicher Pagedefinition Systemspeicher (Stack, Register,...) -4-
c.) Programmbereich?PR?MAIN SECTION CODE WORD 'NCODE' main PROC NEAR GLOBAL main Hier Hauptprogramm einfügen main ENDP Hier Unterprogramme und ISR mit Header einfügen?pr?main ENDS Um die Startadresse kümmert sich der Assembler zusammen mit der Initialisierungsdatei, die vor der Software ausgeführt wird. Nach dem Download der Software in den µc wird die Software automatisch ausgeführt (bzw. steht im debugging-modus zur Verfügung). Die beiden Zeilen?PR?MAIN?PR?MAIN SECTION ENDS CODE WORD 'NCODE' und definieren Anfang und Ende des Code-Bereiches im Speicher. -5-
d.) Unterprogramme Wenn Sie für die Lösung Ihres Problems Unterprogramme verwenden möchten, dann können Sie das nach folgender Syntax machen. Für up_name wählen Sie einen passenden Namen für Ihre Routine. Bitte beachten Sie, dass vergebene Namen nicht doppelt vorkommen dürfen. Das betrifft ebenfalls Sprungmarken, Datenbereiche oder definierte Konstanten. Jedes Unterprogramm wird mit einem Funktionskopf dokumentiert. ---------------------------------------------------------------------------------- Funktionsname: z.b. Warteschleife Version: wenn sinnvoll Autor(en) wer es halt selber geschrieben hat Datum: ---------------------------------------------------------------------------------- Funktion: Beschreibt, was das Programm macht (so 2-3 Zeilen kurze möglichst präzise Beschreibung) ---------------------------------------------------------------------------------- Übergabeparameter: R0 innere Schleife (z.b. Wertbereich: R0 = 0x0fff dh. xy ms) R1 äußere Schleife (ist Multiplikationsfaktor für R0) Ergebnisparameter: - keine ---------------------------------------------------------------------------------- zerstörte Register: Rxy ----------------------------------------------------------------------------------- up_name PROC NEAR Hier Unterprogramm-Code einfügen ret up_name ENDP e.) Interrupt Service Routinen (ISR) Für benötigte Interrupts können Sie folgendes Konstrukt verwenden: ---------------------------------------------------------------------------------- ISR-Name: Timer_T3 Version: wenn sinnvoll Autor(en) wer es halt selber geschrieben hat Datum: ---------------------------------------------------------------------------------- Funktion: Beschreibt, was die ISR so macht (so 2-3 Zeilen kurze möglichst präzise Beschreibung) ---------------------------------------------------------------------------------- Ergebnisparameter: Speicheradresse oder Register ----------------------------------------------------------------------------------- isr_code PROC INTERRUPT = {Interrupt-Nummer} GLOBAL isr_code Hier den Code für die ISR eintragen RETI isr_code ENDP -6-
Welcher Interrupt verwendet wird, wird über die Interrupt-Nummer definiert. Welcher Wert hier eingetragen werden muss, entnehmen Sie bitte dem xc164 Handbuch, Teil 1 (Volume 1 (of 2): System Units) auf Seite 5-12ff. Dieses Dokument finden Sie im Internet auf der Labor Homepage. Der Assembler übernimmt auch automatisch das Setzen der Interrupt Vektor Sprungtabelle. f.) Datenbereich Um Daten (z.b. Tabellen oder Texte) in Ihrem Programmablauf verfügbar zu machen, haben Sie die Möglichkeit diese in einem speziellen Datenbereich zu definieren:?nc?main SECTION DATA WORD 'NCONST' name_word dw 0xA242 name_byte db 0x10?NC?MAIN ENDS Auch diese Daten werden im FLASH abgespeichert. Sie haben also aus Ihrem Assemblerprogramm keinen Schreibzugriff darauf. Für die Ablage der Daten im RAM gibt es einen anderen Bereich:?ND?MAIN SECTION RAM_ODD RAM_WORD dsb dsw?nd?main ENDS DATA WORD 'NDATA' 16 16 Speicherbereiche im RAM Im RAM ist keine Vorbelegung des Speichers wie z.b. im FLASH möglich. Es können nur Speicherbereiche definiert werden. dsb und dsw stehen für Define Storage Byte respektive Define Storage Word. Nach dem Einschalten des µc ist das RAM nicht initialisiert und die dort gespeicherten Werte sind mehr oder weniger zufällig. Hier müssen durch die Software zunächst Daten geschrieben werden, bevor sinnvoll gelesen werden kann. -7-
2.2.3.) Assemblieren, Herunterladen und Ausführen Wenn Sie Ihr Programm so weit geschrieben haben, können Sie Ihr File assemblieren um eventuelle Fehler noch zu finden. Dazu klicken Sie bei geöffnetem File einfach auf folgendes Icon: Im Output Window sollten Sie bei erfolgreicher Übersetzung folgendes sehen: Im nächsten Schritt müssen die übersetzten Files verlinkt werden und ein HEX-File für den Download zum µc generiert werden. Eventuell noch nicht übersetzte Programmteile werden dann automatisch assembliert und mit verlinkt. Hierzu betätigen Sie einfach folgendes Icon: Im Output-Fenster sollten Sie nun in etwa folgenden Meldungen sehen: Nun ist Ihr Programm bereit auf den µc übertragen zu werden. -8-
Das Programm wird durch Betätigen der Schaltfläche zum µc-board übertragen. Dadurch wird der entsprechende FLASH-Bereich im xc164 gelöscht, das assemblierte Pro gramm gespeichert und nach erfolgreicher Übertragung automatisch gestartet. Das Programm läuft nun, und Sie sollten die Ausgaben auf die LEDs sehen können. In der µvision3 Umgebung erkennen Sie eine erfolgreiche Übertragung mit folgender Ausgabe: 2.2.4.) Debug-Möglichkeiten Über die µvision3 Umgebung haben Sie verschiedene Möglichkeiten der Fehlersuche. Bei laufendem Assembler-Programm kann man durch Betätigen des Icons in den Debug-Modus wechseln. Durch erneutes Betätigen beenden Sie den Debug-Modus und sind zurück im Programmier-Modus -9-
Über folgende Icons können Sie verschiedene Funktionen aktivieren. Hier eine Liste der am meisten benötigten Funktionen: Icon Funktion Setzt den µc wieder in den Ursprungszustand und startet die Software neu. Startet das Programm Einzelschritt wird durchgeführt (Auch Unterprogramme werden im Einzelschritt-Modus ausgeführt) Einzelschritt wird durchgeführt (ein eventuell vorhandenes Unterprogramm wird komplett ausgeführt und beim nächsten Befehl nach dem Rücksprung wieder auf Usereingabe gewartet. Haltepunkt setzen Alle Haltepunkte löschen Alle Haltepunkte temporär abschalten Im Hauptfenster können Sie die aktuelle Position im Code verfolgen. Im Fenster auf der linken Seite werden alle Register dargestellt. Die Programmausführung erfolgt auf dem µc, über die USB / JTAG Verbindung werden die entsprechenden Informationen an den PC übertragen. Nutzen Sie diesen ersten Versuch, um sich mit den Funktionalitäten der Keil-µVision Umgebung vertraut zu machen. Die nachfolgenden Versuche werden komplexer und daher sollten Sie mit Ihrem Handwerkszeug vertraut sein! - 10 -
Anzeigen des Speichers im µc In der Keil Entwicklungsumgebung haben Sie eine einfache Möglichkeit den Speicher im Mikrocontroller zu beobachten. Hierzu öffnen Sie im Debug-Modus im Menü View ein Memory Window : Stellen Sie sicher, dass etwas weiter unten im Menü View der Haken bei Periodic Win dow Update gesetzt ist, da Sie sonst eventuelle Aktualisierungen nicht zeitnah im Fenster sehen. Das Speicherfenster wird üblicherweise in die Statuszeile der Keil-Umgebung eingeblendet. Der Übersichtlichkeit halber kann es aber auch abgedockt werden und z.b. auf dem 2. Monitor in passender Größe angezeigt werden. Im Programm-Code haben die verschiedenen Speicherbereiche einen Namen, mit dem Sie im Code adressiert werden können. Dieser Name kann nun einfach in das Feld Address: im Memory-Fenster geschrieben werden. Als Präfix muss nur das Zeichen & ge setzt werden, das dem Keil Debugger mitteilt, dass es sich um eine Adresse handelt. - 11 -
Mit der rechten Maustaste kann man im Speicher-Fenster ein Kontext-Menü anzeigen, über das verschiedene Darstellungsweisen gewählt werden können. Für das Praktikum dürften in erster Linie die Anzeigearten Unsigned Char, Unsigned Short und ASCII von Interesse sein. Gerne aber können Sie auch die anderen Arten ausprobieren. HINWEIS: Wenn Sie mit einer Teilaufgabe fertig sind, ist es das einfachste, das gesamte Projekt zu schließen und auf Explorer Ebene zu kopieren und umzubenennen. Wenn Sie das Projekt im kopierten Ordner wieder öffnen, sind alle zugehörigen Dateien und Einstellungen vorhanden und Sie können weiterarbeiten ohne die ursprünglichen Dateien zu verändern. - 12 -
2.3 Das Projekt Basic Sie müssen das Projekt als ZIP-File von der Labor Homepage herunterladen. Den Namen des Unterverzeichnisses können Sie nach Belieben ändern. Die Dateien im Verzeichnis sollten Sie im Originalzustand belassen und nur über die Keil-Umgebung damit arbeiten. Entpacken Sie das ZIP-File auf die lokalen Festplatte oder auf Ihr G: -Laufwerk. Das Arbeiten von einem USB-Stick kann je nach Typ sehr langsam sein. Vergessen Sie aber nicht eventuelle lokale Kopien Ihrer Projekte zu sichern Nach dem Start der Keil Entwicklungsumgebung öffnen Sie das entpackte Projekt Basic.Uv2. Das eingebettete Assemblerprogramm main.a66 sieht wie folgt aus: ---------------------------------------------------------------------Datei : Einfaches Blink-Programm Datum : Autor : Projekt : XC164-Versuch fuer Praktikum Microcomputertechnik (PMC) Prozessor : XC164CS-16F Aufgabe : Versuch 1 - Einführung ---------------------------------------------------------------------- $SEGMENTED CASE MODV2 $MODINF (43) $INCLUDE(xc164.inc) NCODE NCONST CGROUP DGROUP?PR?MAIN?NC?MAIN ASSUME ASSUME DPP1 : NCONST DPP3 : SYSTEM Konstantendefinition: Wartezeit?PR?MAIN EQU SECTION 0xFFFF Definition der Wartezeit CODE WORD 'NCODE' Hauptprogramm: main PROC NEAR GLOBAL main extr mov mov mov mov toggle: call xorb xorb jmp main #2 DP1L, #0FFh DP1H, #0FFh P1L, #00h P1H, #0FFh Zugriff auf Extended Register (für 2 Befehle) Setzen von Port 1 auf Ausgang wait P1L, #0xff P1H, #0xff cc_uc, toggle Unterprogramm "wait" aufrufen Port 1 invertieren Setzen der Anfangswerte für Port 1 Endlosschleife ENDP - 13 -
Unterprogramme und ISRs wait PROC NEAR Unterprogramm "wait" PUSH MOV R0 R0, #Wartezeit Sichern von R0 Laden des Startwertes R0, #1 cc_nz, wloop wloop: SUB JMP POP RET wait R0 Substraktion der Wartezeit um '1' Wiederholen bis R0 den Wert '0000' erreicht hat Flags werden durch die Substraktion gesetzt Zurückholen von R0 Rücksprung zum Hauptprogram ENDP?PR?MAIN ENDS Datenbereich?NC?MAIN?NC?MAIN SECTION ENDS DATA WORD 'NCONST' END Verwenden Sie dieses Projekt nun als Vorgabe für die Versuche von V1 des Prakti kums. Bitte kopieren Sie nach Ende eines jeden Versuchsteiles das Verzeichnis an eine sichere Stelle, bevor Sie weiterarbeiten. Denken Sie daran, dass Sie am Ende die einzelnen Teile Ihrem Betreuer vorführen müssen. Außerdem gehören zur Abgabe die entsprechenden Teile in Dateiform. - 14 -
2.4 Das Board Abb. 2.4.1: RapidIO Versuchsboard mit XC164 Auf dem Board finden Sie folgende Funktionen, die Sie frei programmieren können: 16 LEDs (Port 1) 4-stellige 7-Segment Anzeige (HEX-fähig, am selben Port (P1) wie LEDs) Dreh-Encoder (2-Kanal mit Push-Button) Intelligentes LC-Display mit Industrie-Standard Hitachikompatiblem Controller 2 Taster für Versuche zum Prellen Cursor-Feld mit insgesamt 6 Tasten 2 Potentiometer für Versuche mit dem internen A/D-Wandler 1-Wire Temperatursensor (derzeit nicht bestückt) Anschlußbuchse für PS/2 Geräte (Tastatur, Maus) Den Schaltplan des Boards finden Sie auf der Homepage des Labors bzw. in ausgedruckter Form an der Tür des Labors. In der nachfolgenden Tabelle auf der folgenden Seite können Sie die Ports der einzelnen Funktionen des Boards nachschlagen. Auf dem Board befindet sich neben dem µc noch ein CPLD, das die Dekodierung für die 7-Segment-Anzeigen sowie deren Mulitplexing übernimmt. - 15 -
Funktion Signalname im Schaltplan Port LED 0 & 7-Segment, 4. Stelle, 20 P1.0 P1L.0 LED 1 & 7-Segment, 4. Stelle, 21 P1.1 P1L.1 LED 2 & 7-Segment, 4. Stelle, 22 P1.2 P1L.2 LED 3 & 7-Segment, 4. Stelle, 23 P1.3 P1L.3 LED 4 & 7-Segment, 3. Stelle, 20 P1.4 P1L.4 LED 5 & 7-Segment, 3. Stelle, 21 P1.5 P1L.5 LED 6 & 7-Segment, 3. Stelle, 22 P1.6 P1L.6 LED 7 & 7-Segment, 3. Stelle, 23 P1.7 P1L.7 LED 8 & 7-Segment, 2. Stelle, 20 P1.8 P1H.0 LED 9 & 7-Segment, 2. Stelle, 21 P1.9 P1H.1 LED 10 & 7-Segment, 2. Stelle, 22 P1.10 P1H.2 LED 11 & 7-Segment, 2. Stelle, 23 P1.11 P1H.3 LED 12 & 7-Segment, 1. Stelle, 20 P1.12 P1H.4 LED 13 & 7-Segment, 1. Stelle, 21 P1.13 P1H.5 LED 14 & 7-Segment, 1. Stelle, 22 P1.14 P1H.6 LED 15 & 7-Segment, 1. Stelle, 23 P1.15 P1H.7 LC-Display, D0 P0.0 P0L.0 LC-Display, D1 P0.1 P0L.1 L-Display, D2 P0.2 P0L.2 LC-Display, D3 P0.3 P0L.3 LC-Display, D4 P0.4 P0L.4 LC-Display, D5 P0.5 P0L.5 LC-Display, D6 P0.6 P0L.6 LC-Display, D7 P0.7 P0L.7 LC-Display, RS (Register Select) P20.4 P20.4 LC-Display, EN (Enable) P20.0 P20.0 LC-Display, WR (Write) P20.1 P20.1 PS/2 Anschluss, Clock KB_CLK P3.13 PS/s Anschluss, Data KB_DATA P3.8, P3.9-16 -
Funktion Signalname im Schaltplan Port Dreh-Encoder, Kanal A ENC0 P5.13 Dreh-Encoder, Kanal B ENC1 P5.14 Dreh-Encoder, Push-Button ENC2 P5.15 Potentiometer 1 AN0 P5.0 Potentiometer 2 AN1 P5.1 1-Wire Temperatursensor 1WIRE P4.1 Prellender Taster 1 (klein) BOUNCE0 P4.2 Prellender Taster 2 (groß, Kontakt 1) BOUNCE1 P4.3 Prellender Taster 2 (groß, Kontakt 2) BOUNCE2 P4.4 Cursor Kreuz, Up S300 P9.0 Cursor Kreuz, Left S301 P9.1 Cursor Kreuz, Right S302 P9.2 Cursor Kreuz, Down S303 P9.3 Cursor Kreuz, Taster 1 S304 P9.4 Cursor Kreuz, Taster 2 S305 P9.5... - 17 -
3 Aufgabe 1: Blinken Aufgabe: Es soll das Programm Basic, beschrieben in Kapitel 2.3, verändert werden. Vorbereitung: Zeichnen Sie einen Programmablaufplan für die neue Warteschleife. Durchführung: Bringen Sie Ihre Änderungen in das Programm ein und testen Sie die Funktion. Probieren Sie auch andere Werte für die Verzögerung aus und beobachten Sie das Ergebnis. Anmerkung: Sie können die Teilversuche einzeln dem Betreuer abnehmen lassen oder am Ende des Termins alle Programme vorführen. Bitte vergessen Sie nicht von den jeweiligen Versionen eine Kopie anzufertigen bevor Sie zur nächsten Aufgabe weitergehen. 3.1 Aufgabenbeschreibung Schließen sie die Rapid I/O-Karte wie in Kapitel 2.2 beschrieben an. Ändern Sie das Unterprogramm wait so ab, dass die Blinkfrequenz noch 1/5 des ursprünglichen Wertes beträgt (die LEDs sollen langsamer blinken, die Wartezeit also 5x so lange sein). Verwenden Sie für den Faktor eine weitere Equate-Anweisung ('EQU'). - 18 -
4 Aufgabe 2: Umgang mit dem Debugger Aufgabe: In dieser Aufgabe sollen Sie lernen, wie mit dem Debugger gearbeitet wird und wie verschiedene Informationen aus dem Programmlauf dargestellt werden können. Der Umgang mit dem Debugger ist essentiell für die Fehlersuche bei Programmen. Vorbereitung: - Laden Sie sich das Projekt Copy_Memory von der Homepage des Labors herunter und analysieren Sie die Funktionen - Erstellen eines Programmablaufplanes für das gegebene Unterprogramm und für die nachfolgenden Aufgaben Durchführung: - Codieren der Programme - Analysieren der Funktionen 4.1 Durchführung 4.1.1 Wortweises Kopieren des FLASH in das RAM Entpacken Sie das Projekt Copy_Memory und öffnen Sie es in Keil. Übersetzen Sie das Programm, laden Sie es aber NICHT auf das Board! Beim späteren Starten des Debuggers wird der Code automatisch auf den µc übertragen. Der Kopiervorgang zwischen FLASH und RAM soll Schritt für Schritt nachvollzogen werden. Starten Sie nun den Debugger über das Menü oder über das Icon. Das Hauptprogramm besteht nur aus einem Unterprogrammaufruf für den Kopiervorgang und einer Endlosschleife, um nach dessen Beendigung einen definierten Zustand einzunehmen. Öffnen Sie ein Speicher-Fenster und laden Sie in zwei Tabs ( Memory #1 und Memory #2 ) die zwei Speicherbereiche, die kopiert werden sollen (FLASH_DATA und RAM_WORD). Nun gehen Sie das Programm im Einzelschrittmodus ( ) durch, und beobachten die Adressregister im Projektfenster sowie die sich ändernden Daten im RAM. Wenn Sie in etwa die Hälfte der Daten im Einzelschrittmodus kopiert haben, machen Sie einen Screenshot des RAM-Bereiches und heften diesen als Ausdruck Ihrer Ausarbeitung bei. Sehen Sie sich das RAM nach dem Kopieren nicht nur in SHORT (Word) Darstellung an, sondern auch in 8-Bit Darstellung (Unsigned Char). Was fällt Ihnen dabei auf? - 19 -
4.1.2 Byteweises Kopieren des FLASH in das RAM Erstellen Sie nun ein zusätzliches Unterprogramm, das den FLASH-Inhalt nicht wortweise, sondern in Bytes in zwei dafür vorgesehene RAM-Bereiche kopiert ( RAM_ODD und RAM_EVEN ). Dabei soll das Low-Byte in den Bereich RAM_ODD und das entsprechende High-Byte in den Bereich RAM_EVEN kopiert werden. Auch hier ist auf das Ende der Tabelle im FLASH abzufragen. Dokumentieren Sie den erfolgreichen Daten-Transfer durch Screenshots der jeweiligen Speicher-Fenster. 4.1.3 Auffüllen des Speichers mit eigenen Werten Schreiben Sie ein Unterprogramm, das zwei weitere Speicherbereiche RAM_COUNT_BIN und RAM_COUNT_ASCII, die jeweils 8 Byte groß sein sollen, mit Werten auffüllt. a) Füllen Sie den Bereich RAM_COUNT_BIN mit den Binärwerten 0x01 bis 0x08 b) Füllen Sie den Bereich RAM_COUNT_ASCII mit den ASCII-Zeichen 1 bis 8 Das Füllen der beiden Bereiche hat in Schleifen zu erfolgen! Diese Art von Software ist Grundlage aller gängigen Spechertest-Verfahren. Dokumentieren Sie das erfolgreichen Füllen des Speichers durch Screenshots der jeweiligen Speicher-Fenster. - 20 -
5 Aufgabe 3: Lauflicht Aufgabe: In dieser Aufgabe soll ein Interrupt-gesteuertes Lauflicht programmiert werden. Im ersten Schritt soll ein Timer konfiguriert werden und in der ISR eine LED zum Blinken gebracht werden. Als zweiter Schritt soll die ISR so abgeändert werden, dass sich ein auf den 16 LEDs hin- und her laufendes Lauflicht ergibt. Vorbereitung: - Überlegen Sie sich die passenden Konfigurationen der Register für Timer und Interruptsteuerung (Siehe Aufgabenblatt in Kapitel 6) - Erstellen Sie Programmablaufpläne für die einzelnen Komponenten des Programms. Durchführung: - Codieren Sie das Programm Lernziele: Erlernen und Handhabung von Bit-Operationen, Umgang mit Interrupts Anmerkung: Dieser Versuchsteil besteht aus 2 Teilaufgaben (siehe Abschnitt '5.2 Durchführung'). Bitte die Assembler Files der jeweiligen Teilaufgabe separat vorführen und abgeben. 5.1 Grundlagen Diese Aufgabe des Versuchs ist mit dem Einsatz eines Timers zu realisieren. In diesem Versuch soll der Timer T3 des XC164 verwendet werden. Es handelt sich um einen 16-Bit-Zähler welcher als Aufwärts- oder Abwärtszähler eingesetzt werden kann. Abb. 5.1: Aufbau und Funktionsweise des Timers T3 Um den Timer wunschgemäß einsetzen zu können, müssen Sie zuerst das zugehörige Konfigurations- und Interruptregister mit den richtigen Bit-Kombinationen belegen. Dies kann in binärer als auch in hexadezimaler Form erfolgen. Der Übersichtlichkeit halber empfiehlt sich die binäre Schreibweise. Die Konfiguration der Register erfolgt am Anfang des Hauptprogramms. Belegung des Konfigurationsregisters (GPT12E_T3CON): - 21 -
D15 D14 D13 D12 D11 D10 D9 D8 D7 D6 D5 D4 D3 D2 D1 D0 RDIR CHDIR EDGE BPS1 BPS1 OTL Tab. 5.2: Konfigurationsregister GPT12E_T3CON OE UDE UD T3R T3M T3M T3M T3I T3I T3I Tab. 5.3: Bitbelegung des Konfigurationsregisters GPT12E_T3CON - 22 -
Die Systemfrequenz des hier verwendeten Systems ist 20 MHz. Ein Interrupt wird im einfachsten Fall immer dann ausgelöst, wenn das Timer-Register überläuft. Überlegen Sie sich ein Teilerverhältnis, das insgesamt für eine blinkende LED und später für ein Lauflicht eine sinnvolle Ansteuerfrequenz ergibt. Als nächstes ist der Timer Mode T3M (Bit D3 bis D5) anzupassen. Stellen Sie die Be triebsart Timer ein. Das Timer Run-Bit (Bit D6) soll auf Run gesetzt werden. Das bedeutet, dass der Timer sofort nach dem Start des Programms läuft. Pin T3 EUD X X 0 1 0 1 Bit T3 UDE 0 0 1 1 1 1 Bit T3 UD 0 1 0 0 1 1 Zählrichtung aufwärts abwärts aufwärts abwärts abwärts aufwärts Tab. 5.4: Funktion der Up- und Down Steuerung Wählen Sie eine Bit-Kombination der Up-Down-Steuerung (Bit D7 und D8) aus der Tabelle 5.4, damit Sie einen Aufwärtszähler erhalten. Das Bit Timer 'Output Enable' (Bit D9) soll eine Ausgabe an Pin P3.3 sperren. Wenn Sie alle Bit-Kombinationen gewählt haben, können Sie mit dem Assembler-Befehl MOV GPT12E_T3CON, #xxxxxxxxxxxxxxxxb das Register belegen. Detaillierte Informationen zur Konfiguration des Timers finden Sie im Handbuch zum XC164: Teil 2: Peripherie-Handbuch, Seite 14ff. - 23 -
Konfiguration des Interruptregisters (GPT12E_T3IC): Ein Überlauf des Timers setzt das Interrupt Request Bit T3IR im zugehörigen Interrupt Control Register und löst damit die zugehörige Interrupt-Service-Routine aus. D15 D14 D13 D12 D11 D10 - - - - - - D9 D8 D7 D6 D5 D4 D3 D2 D1 D0 - GPX IR IE IL VL IL VL IL VL IL VL GL VL GL VL Tab. 5.5: Interruptregister GPT12E_T3IC Zuerst muss der Group Level (D8, D1, D0) eingestellt werden. Er soll hier auf 000 gesetzt werden. Der Interrupt-Level (Bit D5 bis D2) sollte auf 0001 gesetzt werden. Damit der Interrupt freigegeben wird, muss das Interrupt Enable Bit (Bit D6) auf 1 gesetzt werden. Die generelle Freischaltung von Interrupts erfolgt später im Programm mit dem Befehl bset IEN. Das Laden des Registers erfolgt wie im Falle des Timer-Konfigurationsregisters mit dem Befehl MOV GPT12E_T3IC, #xxxxxxxxxxxxxxxxb. Die führenden Nullen können auch hier weggelassen werden, erhöhen aber die Lesbarkeit. Die Interrupt-Service-Routine: Eine Tabelle mit den Interrupt-Nummern finden Sie im Systemhandbuch des µc ab Seite 189 (5-12). Für den Timer 3 ist es die 23h (35d). Diese Interrupt-Nummer muss in der Definition Ihrer ISR entsprechend angegeben werden. (Siehe Kapitel 2) 5.2 Durchführung Schließen sie die Rapid I/O-Karte wie in Kapitel 2.2 beschrieben an. (1) Teilaufgabe 1 Schreiben Sie ein Programm, in dessen Hauptprogramm die Konfiguration der Ports sowie des Timers und der Interrupts erfolgt. Das Programm endet in einer Endlos schleife ohne weitere Befehle. In der Interrupt-Service-Routine sollen nun eine oder mehrere LEDs Ihrer Wahl zum Blinken gebracht werden. Wählen Sie über den Vorteiler eine passende Frequenz. (2) Teilaufgabe 2 Anstelle des Blinklichts soll nun ein Lauflicht in der ISR realisiert werden. Das Lauflicht soll sich über die gesamten 16 LEDs erstrecken. So bald das Lauflicht bei Bit 0 bzw. Bit 15 angelangt ist, soll es die Richtung wechseln. Das Licht soll also auf den 16 LEDs hin und her laufen. - 24 -
Weitere Informationsquellen: 1. Infineon technologies XC164-16 User s Manual, Volume 1 (of 2): System Units 2. Infineon technologies XC164-16 User s Manual, Volume 2 (of 2): Peripheral Units 3. Infineon technologies XC164-16 Data Sheet 4. Infineon technologies, C166S User Manual (Befehlssatz) 5. http://www.infineon.com 6. https://hps.hs-regensburg.de/~fam39454/ie_lab/pmc.php 7. http://www.keil.com 8. G. Schmitt Mikrocomputertechnik mit dem Controller C167, Oldenbourg Wissenschaftsverlag GmbH, München 2000-25 -
6 Begleitende Fragen (Vorbereitung, mit abzugeben!) Zu Aufgabe 1 (Blinken): 1. Warum muß zum Verlangsamen des Blinkens eine zweite Schleife eingefügt werden anstatt den existierenden Wert 0xFFFF zu vergrößern? Zu Aufgabe 2 (Debugger) 2. In der ersten Teilaufgabe wurde der Speicher Wort-weise aus dem FLASH in das RAM kopiert. Wenn nun im Speicher-Fenster des RAMs die Werte als Bytes (Char) dargestellt werden fällt etwas mit der Reihenfolge auf. Was ist das und erklären Sie diesen Effekt? Zu Aufgabe 3 (Timer und Interrupt): Bitte ermitteln Sie für die beiden folgenden Register die Konfigurationswerte: GPT12E_T3CON: 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 12 11 10 9 8 7 6 5 4 3 2 1 0 GPT12E_T3IC: 15 14 13-26 -