2 Hardwarebeschreibung 2.1 Der Mikrocontroller 80C517A

2 Hardwarebeschreibung 2.1 Der Mikrocontroller 80C517A
Institut für Industrielle
Informationstechnik (IIIT)
Universität (TH) Karlsruhe
Hertzstr. 16 / Geb. 06.35
76187 Karlsruhe
Tel.: 0721 608 4521
Fax: 0721 608 4500
Prof. Dr.-Ing. Uwe Kiencke
Prof. Dr.-Ing. habil. K. Dostert
Praktikum:
„Mikrocontroller und digitale
Signalprozessoren“
Versuche 1+2
Einführung in den Mikrocontroller
80C517A
Einführung in den Mikrocontroller 80C517A
2
Einführung in den Mikrocontroller 80C517A
Inhaltsverzeichnis
1
Einleitung ...................................................................................................................... 4
2
Hardwarebeschreibung.................................................................................................. 5
2.1
Der Mikrocontroller 80C517A .................................................................................. 5
2.1.1 Das Registermodell............................................................................................ 6
2.1.2 Das Speicherkonzept.......................................................................................... 7
2.1.3 Die Ports ............................................................................................................ 9
2.1.4 Timer 0 und Timer 1 .......................................................................................... 9
2.1.5 Das Interruptsystem ......................................................................................... 10
2.1.6 Die Capture/Compare-Einheit ......................................................................... 11
2.1.7 Der A/D-Wandler ............................................................................................. 12
2.1.8 Die Multiplikations-/Divisionseinheit ............................................................. 13
2.2
Die Anzeigeneinheit................................................................................................. 13
2.3
Der D/A-Wandler..................................................................................................... 14
3
Die Entwicklungsumgebung ....................................................................................... 15
3.1
Aufbau eines Assemblerprogramms ........................................................................ 15
3.1.1 Befehlsformat................................................................................................... 15
3.1.2 Zahlen .............................................................................................................. 16
3.1.3 Speichertypen................................................................................................... 16
3.1.4 Speicheradressierung ....................................................................................... 17
3.1.5 Direktiven ........................................................................................................ 18
4
3.2
Der Stack.................................................................................................................. 20
3.3
Programmstrukturen ................................................................................................ 21
3.4
Ausmaskierung von Bits .......................................................................................... 24
3.5
Softwareerstellung ................................................................................................... 24
3.6
Das Entwicklungstool Proview................................................................................ 26
Anhang ........................................................................................................................ 28
3
Einführung in den Mikrocontroller 80C517A
1
Einleitung
Die ersten beiden Praktikumsversuche zur digitalen Drehzahlmessung und
Frequenzsynthese werden mit dem Platinenboard „Micky(PL) 1.0“ durchgeführt. Es dient
als Basisplatine zum Minimodul-537 der Firma Phytec, auf dem sich ein Mikrocontroller
vom Typ SAB80C517A der Firma Siemens befindet. Des weiteren ist auf diesem Modul
der externe Speicher des Mikrocontrollers untergebracht. Zur Kommunikation mit einem
PC besitzt das Board eine serielle asynchrone Schnittstelle. Programme können so auf dem
PC erstellt und anschließend in den Programmspeicher des Mikrocontrollers geschrieben
werden. Die zahlreichen Ein- und Ausgänge des eingesetzten Mikrocontrollers werden auf
der Basisplatine herausgeführt. Über vier auf der Platine integrierte LEDs können
programminterne Zustände des Mikrocontrollers angezeigt werden. Die LEDs können über
die unteren vier Bits des Port 5 angesprochen werden. Die Platine wird von einem Netzteil
mit 12V Gleichspannung versorgt.
Im folgenden soll Ihnen nun ein kurzer Einblick in die einzelnen Komponenten des
Versuchsaufbaus gegeben werden. Es wird zuerst der Mikrocontroller 80C517A mit seinen
verschiedenen Hardwareeinheiten vorgestellt und anschließend auf die angebundene
zusätzliche Hardware wie LCD (Liquid Crystal Display) und D/A-Wandler eingegangen.
Das letzte Kapitel gibt eine Einführung in die am Versuchstag zur Verfügung gestellte
Entwicklungsumgebung.
Abbildung 1 Hardware des Praktikumsversuchs
4
Einführung in den Mikrocontroller 80C517A
2
Hardwarebeschreibung
2.1 Der Mikrocontroller 80C517A
Für die Lösung der digitalen Signalverarbeitungsaufgaben in den Versuchen 1 und 2 wird der
Mikrocontroller 80C517A der Firma Siemens verwendet. Er ist ein High-EndMikrocontroller, der abwärtskompatibel zur verbreiteten 8bit 8051-Familie ist. Die
Architektur des Chips wurde um zusätzliche Komponenten wie einen 10bit A/D-Wandler und
eine leistungsfähige Capture-Compare-Einheit erweitert. Für das Praktikum werden nicht alle
Funktionen dieses komplexen Bausteins benötigt. Abbildung 2 zeigt den Aufbau des
Mikrocontrollers.
Abbildung 2 Aufbau des Mikrocontrollers 80C517A
Der Mikrocontroller SAB80C517A zeichnet sich durch folgende Leistungsmerkmale aus:
Ø 56 bidirektionale I/O-Ports und 12 analoge Eingänge
Ø 256 Byte internes RAM und 2 KByte "On Chip" XRAM
Ø 256 direkt adressierbare Bits
Ø 8 Datenzeiger für die Adressierung des externen Speichers
Ø 17 Interruptquellen, 4 Prioritätsebenen
5
Einführung in den Mikrocontroller 80C517A
Ø 16bit Capture-Compare-Unit (CCU)
Ø 10bit A/D-Wandler mit 12 gemultiplexten Eingangskanälen (Konversionszeit 12,4 µs)
Ø 32bit Multiplikations-/Divisionseinheit
Ø 2 serielle Schnittstellen mit variabler Baudratengenerierung
Der Mikrocontroller wird mit einer Oszillatorfrequenz von 18MHz getaktet. Er besitzt einen
umfangreichen Befehlssatz, der im Benutzerhandbuch ab Seite 208 nachgeschlagen werden
kann. Die Abarbeitung der Befehle unterteilt sich in Maschinenzyklen, wobei jeder
Maschinenzyklus aus zwölf Oszillatorperioden besteht. Die meisten Befehle des
SAB80C517A können in einem Maschinenzyklus ausgeführt werden. Andere Befehle wie
z.B. MUL und DIV benötigen dagegen bis zu vier Zyklen für ihre Abarbeitung.
2.1.1 Das Registermodell
Akkumulator (A)
Das Register A ist das Standardregister und wird bei der Durchführung sämtlicher
arithmetischer und logischer Befehle verwendet. Es hat eine Breite von 8 Bit.
Hilfsregister (B)
Dies ist ein frei benutzbares Hilfsregister, das unter anderem bei der Division benötigt wird.
Stackpointer (SP)
Der Stackpointer ist ein 8bit-Register, das immer auf den obersten Wert des Stapelspeichers
zeigt. Er kann nur durch die Befehle PUSH und POP verändert werden.
Programmstatusregister (PSW)
Dieses 8bit-Register enthält alle zur Verfügung stehenden Kennzeichenbits, u.a. das CarryFlag und das Overflow-Flag.
Befehlszähler (PC)
Im 16bit breiten Programmzählregister steht immer die Adresse des nächsten abzuarbeitenden
Befehls.
Datenzeiger (DPTR)
Das DPTR-Register ist ein 16bit-Register, das sich aus zwei 8bit-Registern zusammensetzt.
DPH bildet das Highbyte, DPL das Lowbyte. Der Datenzeiger wird zur Adressierung des
externen Daten- und Programmspeichers verwendet. Er kann auch direkt mit einem 16bitWert geladen werden.
Registersatz R0-R7
Die Register sind jeweils 8bit breit und können frei verwendet werden. Den Registern R0 und
R1 kommt dabei besondere Bedeutung zu, da die indirekte Adressierung nur mit R0, R1 oder
mit dem Datenzeiger DPTR durchgeführt werden kann. Eine Registerbank kann mittels
zweier Bankselect-Bits (Bits RS0 und RS1 im PSW) aktiviert werden. Für die in diesem
6
Einführung in den Mikrocontroller 80C517A
Versuch zu lösenden Aufgaben reichen jedoch die acht Register der voreingestellten Bank 0
völlig aus.
8bit - Register
16bit - Register
A
PCH
PCL
B
DPH
DPL
SP
8 Bit
8 Bit
PSW
Bank 0
Bank 1
Bank 2
Bank 3
Register R0
R0
R0
R0
Register R1
R1
R1
R1
Register R2
R2
R2
R2
Register R3
R3
R3
R3
Register R4
R4
R4
R4
Register R5
R5
R5
R5
Register R6
R6
R6
R6
Register R7
R7
R7
R7
Abbildung 3 Die Register des SAB80C517A
2.1.2 Das Speicherkonzept
Der Speicher teilt sich auf in einen internen und einen externen Anteil.
Der interne Speicher
Der Mikrocontroller 80C517A verfügt über 256 Byte internen Datenspeicher. Das interne
RAM kann im Bereich 00h bis 7Fh direkt oder indirekt adressiert werden (siehe 3.1.4
Speicheradressierung). Es besteht aus acht 8bit-Registern, 16 bitadressierbaren Byte (128 Bit)
und 80 frei verfügbaren Byte. Das obere interne RAM im Adreßbereich 80h bis FFh enthält
Datenbytes, die ebenfalls frei benutzt werden können. Parallel zu diesem Adreßbereich
befinden sich 128 Bytes, in denen die Spezialfunktionsregister untergebracht sind. Die
Spezialfunktionsregister (SFR) stellen die Verbindung zu der integrierten Peripherie des
Controllers wie z.B. Timern oder Ports her. Der gesamte Kontroll- und Datenfluß der
Peripherie wird ausschließlich über diese Register abgewickelt. Die SFRs sind im
Benutzerhandbuch ab Seite 38 beschrieben.
7
Einführung in den Mikrocontroller 80C517A
Abbildung 4 Datenspeicher des 80C517A
Die oberen 128 Bytes des internen Datenspeichers teilen sich somit in zwei Funktionsbereiche
auf, die lediglich durch die Art der Adressierung unterschieden werden. Wird der Bereich 80h
bis FFh direkt adressiert, z.B. durch den Befehl mov 80h,#01, so erreicht man die
Spezialfunktionsregister. In diesem Speicherbereich befinden sich auch die CPU-Register A,
B, DPH und DPL etc. Die parallel zu den SFRs liegenden Datenbytes können nur mit
Befehlen erreicht werden, die indirekt adressieren, z.B. durch den Befehl mov @R0,A ,
wobei in R0 die Speicheradresse steht. Die Datenbytes besitzen jedoch die gleichen Adressen
wie die SFRs. Insgesamt stehen 81 SFR zur Verfügung, von denen 15 zusätzlich
bitadressierbar sind.
Der externe Speicher
Der externe Speicher ist an den Adreß- und Datenbus des Mikrocontrollers angebunden. Er
gliedert sich in einen Codespeicher, in dem das Programm abgelegt wird, und einen
Datenspeicher, der dem Programmierer uneingeschränkt zur Verfügung steht. Code- und
Datenspeicher haben jeweils eine Größe von 64 kByte. Auf den externen Speicher kann nur
mittels indirekter Adressierung zugegriffen werden, es ist also stets ein Zeiger zu verwenden.
Mit den 8bit-Registern R0 und R1 können nur die unteren 256 Bytes des Adreßraumes
erreicht werden. Aus diesem Grund ist für die Adressierung des externen Speichers der
Datenzeiger DPTR vorgesehen. Da dieser 16bit breit ist, läßt sich mit ihm der gesamte 64
kByte Speicher adressieren.
Als Programmspeicher kommt ein externes Flash-EEPROM zum Einsatz. Die FlashSpeichertechnologie erlaubt es, den Programmspeicher wie ein EPROM zu beschreiben und
wie ein EEPROM zu löschen. Dies hat den Vorteil, daß er bei einer Neuprogrammierung nicht
entnommen werden muß. Der Bereich 0000h bis 00ABh des Programmspeichers ist für die
Interrupteinsprungvektoren reserviert und darf nicht überschrieben werden. Im Anhang A
8
Einführung in den Mikrocontroller 80C517A
befindet sich eine detaillierte Speicherbelegung sowie eine Übersicht der InterruptVektoradressen.
2.1.3 Die Ports
Der Mikrocontroller 80C517A verfügt über neun Ports, auf die mit Hilfe der
Spezialfunktionsregister P0 bis P8 zugegriffen wird. Bei den Ports P0 bis P6 handelt es sich
um 8bit breite bidirektionale I/O-Ports, wobei P0 und P2 für den Adreß-/Datenbus reserviert
sind. Neben diesen digitalen Ports besitzt der Mikrocontroller zwei analoge Ports P7 und P8.
An diesen Ports sind die 12 Kanäle des A/D-Wandlers herausgeführt. Den meisten Portpins ist
eine alternative Funktion zugeordnet. Dabei handelt es sich um Ein- und Ausgangsleitungen
von Peripherieeinheiten wie beispielsweise Timern, seriellen Schnittstellen oder dem
Interruptsystem. Die für das Praktikum benötigten Portpins sind in Tabelle 1 aufgelistet.
Pin
Alternative Funktion
P3.4
T0
Zähleingang Timer 0
P1.1
INT4/CC1
Externer Interrupt 4/Capture-Compare-Register 1
Port
P7.0
A/D-Kanal 0
Tabelle 1 Die Portpins und ihre alternative Funktion
2.1.4 Timer 0 und Timer 1
Die beiden Timer 0 und 1 sind in ihrem Aufbau identisch. Sie unterteilen sich in zwei 8bitRegister, TH0 und TL0 bei Timer 0 bzw. TH1 und TL1 bei Timer1 und können als Zähler
oder Zeitgeber programmiert werden. Die Betriebsart kann im SFR TMOD eingestellt
werden. In der Betriebsart als Zeitgeber wird das Zählregister in jedem Maschinenzyklus um
eins erhöht. Da ein Maschinenzyklus aus zwölf Oszillatorperioden besteht, beträgt die
Zählrate 1/12 der Oszillatorfrequenz. In der Betriebsart als Zähler erfolgt ein Zählschritt bei
jeder fallenden Flanke am entsprechenden Eingangspin. Für Timer0 ist Pin 3.4 der
Zählereingang, für Timer1 ist es Pin 3.5.
In der Betriebsart 1 arbeitet Timer0 als 16bit-Timer/Zähler, in der Betriebsart 2 im 8bitAutoreload. Im Autoreload-Modus besteht das Zählregister nur aus TL0. Bei einem Überlauf
dieses Registers, also dem Übergang vom Zählerstand FFh zu 00h, wird der Wert des
Registers TH0 in TL0 geschrieben. Dies geschieht automatisch durch die Hardware. Soll der
Zähler nach der Zeit t überlaufen, so berechnet sich der Reloadwert für TH0 zu:
Reloadwert = 256 − t ∗
f OSZ
12
9
Einführung in den Mikrocontroller 80C517A
2.1.5 Das Interruptsystem
Der SAB80C517A besitzt ein umfangreiches Interruptsystem mit sieben externen
Interruptleitungen. Interrupts können durch steigende oder fallende Flanken an den
Interrupteingängen oder durch die interne Peripherie, z.B. durch einen Timer-Überlauf oder
das Ende eines Wandlungsvorgangs im A/D-Wandler, ausgelöst werden. Tritt ein solches
Ereignis auf, wird ein speziell ihm zugeordnetes Bit, das Interrupt-Request-Flag, gesetzt. Eine
Interruptanforderung wird jedoch nur bearbeitet, falls der Interrupt zugelassen ist. Jeder
Interrupt kann individuell zugelassen und gesperrt werden, indem das korrespondierende
Interrupt-Enable-Flag gesetzt bzw. gelöscht wird. Zusätzlich können alle Interrupts
gemeinsam gesperrt werden, indem das globale Interrupt-Flag EAL gelöscht wird.
Eine Unterbrechungsanforderung veranlaßt den Mikrocontroller, die momentane
Befehlssequenz zu unterbrechen und eine Interruptserviceroutine (ISR) auszuführen. Zunächst
wird die Rücksprungadresse auf den Stack gerettet. Danach verzweigt der Programmlauf auf
eine fest zugeordnete Adresse im Codespeicherbereich 0003h bis 00ABh, die sogenannte
Interrupt-Vektoradresse. An dieser Adresse steht ein Sprungbefehl zu der eigentlichen
Interruptserviceroutine, die an einem beliebigen Platz im Codespeicher stehen kann. Eine
Übersicht der Interrupt-Vektoradressen des SAB80C517A finden Sie im Anhang. Nach
Abarbeitung der ISR wird wieder zum ursprünglichen Programm zurückgekehrt. Das
Interrupt-Flag, das für die Auslösung eines Interrupts verantwortlich war, wird bei einigen
Interruptquellen automatisch zurückgesetzt, bei anderen muß dies softwaremäßig erfolgen.
Geschieht dies nicht, wird direkt nach Abarbeitung der Interruptroutine erneut ein Interrupt
ausgelöst und das Programm „hängt“ sich in der ISR auf. Die Ausführung der Interruptroutine
ist vergleichbar mit dem Aufruf eines Unterprogramms. Der Unterschied besteht darin, daß
eine Interruptroutine mit dem Befehl RETI (Return from Interrupt) anstatt RET (Return from
Subroutine) abgeschlossen werden muß. An diesem Befehl erkennt der Prozessor das Ende
der ISR, restauriert die zuvor gesicherten Stackinformationen und kehrt ordnungsgemäß ins
Hauptprogramm zurück.
Sind mehrere Interruptquellen zugelassen, kann es bei ihrer Abarbeitung zu
Überschneidungen kommen. Einerseits kann ein Interrupt durch einen anderen unterbrochen
werden, andererseits können zwei Interrupts gleichzeitig ausgelöst werden. Um dies zu
verhindern, werden den Interruptquellen Prioritäten zugeordnet. Die Interruptquellen sind in
Gruppen zu je drei Interrupts zusammengefaßt. Jeder Gruppe kann eine der vier
Prioritätsstufen zugewiesen werden. Dies geschieht durch Setzen der entsprechenden Bits in
den Registern IP0 und IP1. Die höchste Priorität für einen Interrupt ist die Ebene 3, die
niedrigste die Ebene 0. Interrupts, die einer höheren Ebene zugeordnet sind, können nicht von
Interrupts niedrigerer Ebenen unterbrochen werden. Sie werden abgewiesen.
Interrupts gleicher Ebene werden nach einer prozessorintern festgelegten Abarbeitungsfolge
angenommen, die in Tabelle 2 dargestellt ist. Jeweils drei Interruptquellen sind zu einer
Gruppe zusammengefaßt. Die Priorität innerhalb einer Gruppe nimmt von links nach rechts
ab, die Priorität unter den Gruppen nimmt von oben nach unten ab.
10
Einführung in den Mikrocontroller 80C517A
Priorität
Hoch
→
Hoch
Externer Interrupt 0
Serielle Schnittstelle 1

Timer 0 Interrupt
↓
Niedrig
Niedrig
A/D-Wandler Interrupt
Externer Interrupt 2
Externer Interrupt 1
CM0-CM7-Interrupt
Externer Interrupt 3
Timer1 Interrupt
Compare-Timer Interrupt
Externer Interrupt 4
Serielle Schnittstelle 0
COMSET Interrupt
Externer Interrupt 5
Timer 2 Interrupt
COMCLR Interrupt
Externer Interrupt 6
Tabelle 2 Priorität für Interruptquellen gleicher Ebene
Timer0 und Timer1-Interrupt
Diese Interrupts werden durch Überläufe der beiden Timer ausgelöst, also beim Übergang des
Zählerstandes von FFh auf 00h. Die zugehörigen Interrupt-Request-Flags werden automatisch
zurückgesetzt.
Der A/D-Wandler-Interrupt
Dieser Interrupt wird vom A/D-Wandler ausgelöst, wenn das Ergebnis einer Wandlung
vorliegt. Das zugehörige Interrupt-Flag IADC muß per Software zurückgesetzt werden. Ist der
Wandler auf kontinuierliche Wandlung eingestellt, so wird das IADC-Flag nach jedem
Wandlungszyklus gesetzt.
Externer Interrupt 4
Dieser Interrupt wird durch eine positive Flanke am Pin INT4 ausgelöst und setzt das
Interrupt-Request-Flag IEX4. Dieses Flag wird durch die Hardware automatisch
zurückgesetzt.
Timer2-Interrupt
Dieser Interrupt kann von zwei verschiedenen Ereignissen erzeugt werden. Der Überlauf von
Timer2 setzt das Interrupt-Request-Flag TF2, eine negative Flanke am Pin T2EX setzt das
Interrupt-Request-Flag EXF2. Beide Ereignisse verzweigen auf dieselbe Interruptroutine
(002Bh). Um die Interruptquelle in der Serviceroutine erkennen zu können, werden die Flags
nicht automatisch zurückgesetzt. Dieses Flag muß softwaremäßig vor Ende der
Interruptroutine zurückgesetzt werden.
2.1.6 Die Capture/Compare-Einheit
Eine der leistungsstärksten Einheiten des 80C517A ist die Capture/Compare-Einheit (CCU).
Sie stellt ein komfortables Hilfsmittel zur Verarbeitung externer Ereignisse und zur Erzeugung
von digitalen Signalen wie z.B. Impulsfolgen oder Pulsweitenmodulation dar. Als Zeitbasis
dienen zwei Timer, der Compare-Timer und Timer2. Beide Timer haben eine Breite von 16
Bit. Da im Praktikum der Compare-Timer nicht benötigt wird, wird im folgenden nur die
Funktion des Timer2 beschrieben.
11
Einführung in den Mikrocontroller 80C517A
Die maximale Taktfrequenz von Timer2 beträgt fOSZ/12. Timer2 bietet in seinen
Standardfunktionen eine Vielzahl von Steuerungsmöglichkeiten. Er besteht aus einem 16bitZählregister (TH2, TL2), das als intern gesteuerter Zeitgeber (Timer), extern freigegebener
Zeitgeber (gated timer) oder als extern getakteter Zähler (event counter) programmiert werden
kann. Die Betriebsart des Timer2 läßt sich im Spezialfunktionsregister T2CON einstellen. Die
Erhöhung des Zählerstandes kann entweder über 1/12 oder 1/24 der Oszillatorfrequenz
erfolgen, d.h. mit jedem Maschinenzyklus oder nur mit jedem zweiten. Die Einstellung erfolgt
durch das Bit T2PS im SFR T2CON. Wird Timer2 im Zählermodus verwendet, muß das Bit
T2PS1 im Register CTCON zu Null gesetzt werden. Timer2 besitzt einen Reloadmodus. Bei
einem Überlauf wird der Inhalt des Registers CRCL und CRCH automatisch in das
Zählregister geladen. Dieser Überlauf ermöglicht es, Interrupts in äquidistanten Zeitabständen
auszulösen. Die Zeit zwischen zwei Interrupts berechnet sich zu
tOverflow =
65536 − (CRCL + 256 ∗ CRCH ) (T 2 PS + 2∗T 2 PS 1)
∗2
f OSZ / 12
Der Autoreload kann alternativ auch durch ein externes Signal ausgelöst werden. Die CCU
besitzt zwei Funktionen, die Compare- und die Capturefunktion. Im folgenden wird die in
Versuch 1 benötigte Capture-Funktion beschrieben.
In dieser Betriebsart dient Timer2 als Zeitbasis. Bei Eintritt eines externen Ereignisses wird
der momentane Zählerstand in das zugeordnete Capture-Register geschrieben und dort
gespeichert. Dieses Ereignis kann z.B. eine steigende Flanke an Pin P1.1 (CC1) sein.
Zusätzlich wird bei einem Capture-Ereignis das entsprechende Interrupt-Flag gesetzt. Ist der
zugehörige Input-Capture-Interrupt freigegeben, so wird dieser bei jeder aktiven Flanke am
Triggereingang ausgelöst. In der Interrupt-Routine kann nun der Inhalt des Capture-Registers
ausgelesen und verarbeitet werden.
Timer2 ist mit den Capture/Compare-Registern CC1 bis CC4 und dem CRC-Register
verknüpft. Somit können bis zu fünf Signale gleichzeitig ausgemessen werden. Die Funktion
der CCx-Register wird im SFR CCEN eingestellt. Mit der Capture/Compare-Einheit können
somit ohne großen Softwareaufwand Zeitdifferenzen zwischen Signalen ausgemessen werden.
Bei der Periodendauermessung z.B. ist die zu messende Zeitdauer durch den Abstand zweier
Signalflanken gleicher Polarität (entweder steigende oder fallende Flanke) vorgegeben.
2.1.7 Der A/D-Wandler
Der integrierte A/D-Wandler des Mikrocontrollers 80C517A besitzt 12 gemultiplexte
Eingangsleitungen bei einer Auflösung von 10 Bit. Er arbeitet nach dem Prinzip der
sukzessiven Approximation und besitzt eine Wandlungszeit von ca. 12,4 µs. Der maximale
Fehler einer Wandlung beträgt ±2 LSB (Least Significant Bits). Die Analogeingänge sind an
den Ports 7 und 8 herausgeführt.
Vor einer Wandlung muß der Eingangskanal gewählt werden, der in den Registern ADCON0
oder ADCON1 eingestellt werden kann. Durch einen Schreibzugriff auf das Register
ADDATL wird eine Wandlung gestartet. Das BSY-Flag wird im nächsten Zyklus nach
Eintreffen des Startsignals gesetzt und mit dem Ende der A/D-Wandlung wieder
zurückgesetzt. Danach kann das Ergebnis aus den Registern ADDATH und ADDATL
12
Einführung in den Mikrocontroller 80C517A
ausgelesen werden. Für das Praktikum genügen die oberen 8 Bits des Wandlungsergebnisses,
welche im ADDATH-Register stehen. Die nächste Wandlung beginnt mit einem erneuten
Schreibzugriff auf ADDATL.
2.1.8 Die Multiplikations-/Divisionseinheit
Der 80C517A besitzt eine 32bit Arithmetikeinheit, mit der schnelle Multiplikationen und
Divisionen durchgeführt werden können. Während die Befehle MUL und DIV nur 8bitOperanden zulassen, unterstützt die Arithmetikeinheit 32bit-Division und 16bitMultiplikation. Sie ist als Coprozessor ausgeführt und arbeitet unabhängig von der CPU. Für
die Operanden stehen die SFR MD0 bis MD5 zur Verfügung. Die Berechnung kann zwischen
4 und 6 Maschinenzyklen benötigen. In dieser Zeit kann der Mikrocontroller andere Aufgaben
erledigen. Erst danach kann das Ergebnis aus den Registern MD0 bis MD5 gelesen werden.
2.2 Die Anzeigeneinheit
Zur Anzeige von Meßergebnissen des Mikrocontrollers und zur Ausgabe von Meldungen an
den Benutzer ist das Board mit einem Anzeigenmodul (LCD) ausgestattet. Es ist über einen
Adreßdekoder an den Controllerbus angebunden und wird wie ein externer RAM-Baustein
angesprochen. Die Integration in den Adreß-/Datenbus hat den Vorteil, daß kostbare
Portanschlüsse eingespart werden und die Ansteuerung des Displays durch die Software
wesentlich schneller und komfortabler erfolgen kann. Das Anzeigenmodul besteht aus einer
LCD-Punkt-Matrix, einem Grafikcontroller, einem Anzeigenspeicher und einer integrierten
Ansteuerlogik. Es ist in der Lage, zwei Zeilen mit jeweils 16 Zeichen darzustellen. Der
Grafikcontroller besitzt ein Charakter-ROM, in dem die Zeichencodes der darstellbaren
Zeichen gespeichert sind. Ein Zeichen setzt sich aus einer 5x7-Punktmatrix zusammen.
Im Anzeigenspeicher stehen die Codes der Zeichen, die auf dem Display dargestellt werden
sollen. Er besitzt eine Größe von 80 Bytes. Jedes Byte repräsentiert einen Anzeigenplatz auf
dem Display, es bildet also einen Vektor in das Charakter-ROM, von wo sich der
Grafikcontroller das entsprechende Muster für das Zeichen holt. Der Zeichensatz umfaßt mit
kleinen Ausnahmen den ASCII-Code (Zeichencodes 20h bis 7Dh). Der Adreßbereich
erstreckt sich für die 16 Zeichen der ersten Zeile von 00h bis 0Fh, für die 16 Zeichen der
zweiten Zeile von 40h bis 4Fh.
Der Grafikcontroller besitzt einige Befehle, mit denen er die Anzeige steuern kann, z.B. um
das Display ein- und auszuschalten oder den Anzeigenspeicher zu löschen (siehe Anhang).
Neben den Befehlsbytes empfängt er Datenbytes. Zur Unterscheidung werden die Leitungen
RS (Register Select) und R/W (Read/Write) verwendet, die an die Adreßleitungen A0 und A1
des Adreßbusses angeschlossen sind. Für die Ansteuerung der Anzeigeneinheit sind die
Adressen FE00h bis FE03h im I/O-Adreßbereich des Mikrocontrollers reserviert. Die
Ankopplung des Displays an den Adreß-/Datenbus zeigt Abbildung 5.
13
Einführung in den Mikrocontroller 80C517A
Abbildung 5
Anbindung des LCD-Displays an den Adreß-/Datenbus des
80C517A
2.3 Der D/A-Wandler
Zur Ausgabe von analogen Spannungen wird der D/A-Wandler AD7801 der Firma Analog
Devices verwendet. Dabei handelt es sich um einen Wandlerbaustein mit 8bit Auflösung und
einer Genauigkeit von ±1 LSB. Er liefert eine Ausgangsspannung von 0V bis 5V und besitzt
eine Wandlungszeit von 2µs.
Der D/A-Wandler ist wie die Anzeigeneinheit in den Adreß-/Datenbus des Mikrocontrollers
80C517A integriert und wird wie ein RAM-Baustein angesprochen. Er erhält die Datenbytes
vom 8bit-Datenbus des Mikrocontrollers und wird über den Adreßdekoder durch einen
Schreibzugriff auf die I/O-Adresse FF00h des externen Datenspeichers angesprochen.
Abbildung 6
14
Anbindung des D/A-Wandlers an den Adreß-/Datenbus des
80C517A
Einführung in den Mikrocontroller 80C517A
3
Die Entwicklungsumgebung
In diesem Kapitel wird die Ihnen zur Verfügung stehende Software zur Erstellung der
Programme für den Mikrocontroller vorgestellt. Die Softwareentwicklung für den
Mikrocontroller 80C517A geschieht in Assembler. Im folgenden sollen einige Besonderheiten
der Assemblerprogrammierung hervorgehoben und eine kurze Einführung in die
Programmiersprache gegeben werden. Eine detaillierte Beschreibung würde den Rahmen
dieses Versuches sprengen. Es sei auf einschlägige Literatur zu diesem Thema verwiesen.
3.1 Aufbau eines Assemblerprogramms
3.1.1 Befehlsformat
Der Programmcode besteht aus Assemblerbefehlen, die der Assembler beim Compilieren in
Maschinencode übersetzt und diesen in einer Objektdatei speichert. Assemblerbefehle haben
folgenden Aufbau:
[Label:] Mnemonic [Operand] [, Operand] [, Operand] [;Kommentar]
Label
Ein Label ist eine virtuelle Adresse, deren physikalischer Wert erst beim Compilieren
ermittelt wird. Labels sind Namen und müssen mit einem Doppelpunkt enden. Diese Stelle
des Programms kann dann durch Angabe des Labels angesprochen werden. Labels werden
z.B. bei Sprungbefehlen zur Angabe von relativen Adressen benutzt. Dort muß allerdings der
Doppelpunkt weggelassen werden.
Mnemonic
Ein Mnemonic ist ein Assemblerbefehl, z.B. mov, der beim Assemblieren in einen
Maschinencode übersetzt wird. Dieser Assemblerbefehl kann bis zu drei Operanden besitzen.
Operanden
Operanden sind Argumente oder Ausdrücke, die im Zusammenhang mit Assemblerdirektiven
oder Befehlen verwendet werden.
Kommentare
Ein Assemblerprogramm sollte gut dokumentiert werden. Kommentare erleichtern die
Bearbeitung des Quellcodes und die anschließende Fehlersuche erheblich. Sie werden mit
einem Semikolon eingeleitet und können an beliebiger Stelle stehen. Alle Zeichen, die hinter
diesem Semikolon stehen, werden beim Assemblieren ignoriert und erzeugen keinen
Programmcode.
15
Einführung in den Mikrocontroller 80C517A
3.1.2 Zahlen
Zahlen können Konstanten oder Adreßangaben sein. Konstanten sind immer vom Typ Byte,
während Adressen vom Typ Byte oder Word sein können. Adressen im internen RAM sind
dagegen stets vom Typ Byte.
Bytes können als Dezimal-, Binär- oder Hexadezimalzahl angegeben werden. Auch die
Angabe als Charakterzeichen ist erlaubt:
120
28d
3Fh
´A´
10111001b
=
=
=
=
=
120
28
63
65
185
Bei der Angabe von Hexadezimalzahlen, die mit einem Buchstaben beginnen, ist zu beachten,
daß der Assembler eine führende Null erwartet. Einem konstanten Wert muß stets ein
Nummernzeichen (´#´) vorangestellt werden, ansonsten wird er vom Assembler als Adresse
interpretiert.
3.1.3 Speichertypen
Der Assembler unterstützt die nachfolgenden Speichertypen. Jede Variable kann durch den
Speichertyp explizit im internen und externen Speicher plaziert werden. Zugriffe auf den
internen Datenspeicher laufen wesentlich schneller ab als Zugriffe auf den externen
Datenspeicher. Deshalb ist es sinnvoll, häufig benutzte Variablen im internen Datenspeicher
unterzubringen. Große Datenmengen wie z.B. Tabellen müssen dagegen im externen Speicher
plaziert werden.
Speichertyp
Adreßbereich
Beschreibung
DATA
0000h – 007Fh
Direkt adressierbarer interner Speicher
BIT
0020h – 002Fh
Bitadressierbarer interner Speicher
IDATA
0000h – 00FFh
Indirekt adressierbarer interner
Speicher
XDATA
0000h – FFFFh
64 KB externer Datenspeicher
CODE
0000h – FFFFh
64 KB Programmspeicher
CONST
0000h – FFFFh
Wie CODE, kann nur für ROMKonstanten verwendet werden
Tabelle 3 Speichertypen
16
Einführung in den Mikrocontroller 80C517A
3.1.4 Speicheradressierung
Die Speicheradressierung ist für die Bearbeitung der Versuchsaufgaben von großer
Bedeutung, da neben dem internen und externen Speicher auch das LCD und der D/AWandler über den Adreß-/Datenbus angesprochen werden. Es gibt verschiedene Arten der
Speicheradressierung, die im folgenden vorgestellt werden.
Unmittelbare Adressierung
Bei der unmittelbaren Adressierung wird die Adresse als Konstantenwert angegeben, z.B.
mov 80h,#10
Direkte Adressierung
Die direkte Adressierungsart ermöglicht den Zugriff auf die SFR-Register und die unteren
128 Bytes des internen Datenspeichers. Direkte Adressen sind stets 8bit-Werte. Für die
Spezialfunktionsregister sind Symbole definiert, die die Adressierung vereinfachen. Ein
Schreibzugriff auf Port1 hat z.B. folgende Gestalt
mov P1,#25
Indirekte Adressierung
Als Zeigerregister für die indirekte Adressierung werden die 8bit-Register R0, R1 sowie der
16bit breite Datenzeiger DPTR verwendet. Mit R0 und R1 kann nur auf das interne RAM
oder auf 256 Byte große Blöcke des externen RAMs zugegriffen werden. Der 16bit breite
DPTR ermöglicht dagegen den Zugriff auf den gesamten 64kByte-Speicherbereich.
interner RAM-Zugriff:
@R0, @R1
externer RAM-Zugriff:
@R0, @R1, @DPTR
Alle Befehle zum Ansprechen des externen Programm- oder Datenspeichers arbeiten nur über
den Akkumulator A. Auf den Programmspeicher wird mit dem movc-Befehl zugegriffen, auf
externe Daten mit dem movx-Befehl.
Der DPTR kann mit einer absoluten Adresse oder einem Label geladen werden, z.B.
mov
movx
mov
movx
dptr,3F00h
A,@dptr
dptr,#LABEL
@dptr,A
;Inhalt von Adresse 3F00h in Akku holen
;Inhalt von Akku an Adresse, die durch Label
;spezifiziert ist, schreiben
Indirekt indizierte Adressierung
Sind Werte in Form einer Tabelle im Speicher abgelegt, bietet sich die indirekt indizierte
Adressierung mit Hilfe des movc-Befehls an:
movc A,@A+<Basisadresse>
Die Basisadresse entspricht der niedrigsten Tabellenadresse und ist ein 16bit-Wert. Dies
erzwingt die Verwendung des Datenzeigers DPTR. Der Inhalt des Akkumulators wird zur
17
Einführung in den Mikrocontroller 80C517A
Basisadresse hinzuaddiert und die Summe als Adresse interpretiert. Der Inhalt der Adresse
wird in den Akku geladen. Der Akkumulator dient dabei als Index auf die Tabelle.
movc A,@A+dptr
Hinweis: Da der movx-Befehl im Gegensatz zum movc-Befehl nicht indirekt indiziert
arbeitet, müssen Wertetabellen immer im Programmspeicher abgelegt werden.
Bitadressierung
Bitadressen repräsentieren die exakte Adresse eines Bits im Speicher. Auf Bits eines Bytes,
das sich im bitadressierbaren Speicherbereich (20h bis 2Fh) befindet, kann über einen Punkt
´.´ zugegriffen werden.
;Bit 0 der Adresse 20h setzen
;Bit 7 im Akkumulator löschen
setb 20h.0
clr ACC.7
3.1.5 Direktiven
Der Assembler kennt sämtliche Direktiven, welche die Definition von Symbolen, die
Reservierung von Speicher und die Plazierung von Programmcode erlauben. Die Direktiven
dürfen nicht mit Befehlen verwechselt werden. Sie erzeugen keinen Programmcode.
Die Include-Direktive
Die Include-Direktive fügt die angegebene Quelldatei beim Compilieren an dieser Stelle ein.
$include(Dateiname)
Mit dieser Direktive werden z.B. die Symboldefinitionen der SFRs des 80C517A, die sich in
der Datei REG517A.INC befinden, in das Hauptprogramm eingebunden.
Die EQU-Direktive
Die Equate-Direktive ermöglicht es, Symbole zu verwenden, die numerische oder
Zeichenkettenkonstanten repräsentieren. Sie erzeugt symbolische Konstanten.
name
equ
ausdruck
Symbole können mit den Direktiven EQU und SET erzeugt werden. Symbole, die mit der
EQU-Direktive erzeugt wurden, können im Verlauf des Programms nicht mehr neu definiert
werden. Symbole, die durch SET erzeugt wurden, können beliebig oft definiert werden.
Die Segment-Direktive
Ein Segment ist ein Block im Daten- oder Programmspeicher, den der Assembler aus dem
Quellcode erstellt. Der Mikrocontroller besitzt verschiedene Speicherbereiche wie z.B.
Programmspeicher, Datenspeicher, Spezialfunktionsregister und externen Datenspeicher.
Segmente werden verwendet, um Programmcode, Konstanten und Variablen in diesen
Speicherbereichen zu plazieren. Es gibt zwei verschiedene Arten von Segmenten: relokatible
und absolute Segmente:
Relokatible Segmente besitzen einen Namen und einen Speichertyp. Relokatible Segmente,
die den gleichen Namen besitzen, jedoch aus unterschiedlichen Objektdateien stammen,
18
Einführung in den Mikrocontroller 80C517A
werden beim Link-Prozeß zusammengefügt. Diese Segmente werden folgendermaßen
erzeugt:
prog
segment
code
definiert ein Segment namens prog mit dem Speichertyp code. Das bedeutet, daß die Daten
im Segment prog im Programmspeicher abgelegt werden. Haben Sie ein Segment definiert,
müssen Sie dieses auswählen. Dies geschieht mit der RSEG-Direktive. Ein Segment wird
folgendermaßen aktiviert:
rseg
prog
Diese Direktive gilt für den nachfolgenden Code, bis das Segment gewechselt wird.
Absolute Segmente befinden sich in festen Speicherbereichen und besitzen keinen Namen.
Der Linker kann sie im Gegensatz zu relokatiblen Segmenten nicht verschieben und auch
nicht mit anderen Segmenten kombinieren. Absolute Segmente werden mit den Direktiven
CSEG, DSEG oder XSEG erzeugt. Mit ihnen können Programmcode und Daten an festen
Speicheradressen plaziert werden.
cseg
at
adresse
Die Using-Direktive
Mit der Using-Direktive kann zwischen den vier vorhandenen Registerbänken des
Mikrocontrollers gewechselt werden. Registerbank 0 ist voreingestellt und reicht für die
Bearbeitung der Praktikumsaufgaben vollkommen aus.
Die Public/Extrn-Direktive
Die Public-Direktive macht ein Symbol, eine Variable oder ein Label für andere
Objektmodule bekannt. Um dieses Symbol in anderen Objektmodulen zu verwenden, muß es
dort mit der Extrn-Direktive eingebunden werden.
Symbole können einen Wert, einen Textblock, eine Adresse oder ein Register repräsentieren.
Sie können auch für numerische Konstanten und Ausdrücke verwendet werden.
PUBLIC label
EXTRN segment(label)
Die DS-Direktive
Die DS-Direktive reserviert eine bestimmte Anzahl von Bytes an der aktuellen Adresse im
aktuellen Segment.
variable:
DS
2
;reserviert 2 Bytes für variable
Die DB/DW-Direktive
Die DB-Direktive und die DW-Direktive erlauben die Definition von Konstanten im
Programmspeicher. Zur Initialisierung von Datenbytes wird die DB-Direktive verwendet. Mit
ihr werden üblicherweise Zeichenkettenvariablen initialisiert. Der Initialisierungswert wird als
String-Konstante oder als Folge von Bytes angegeben. Das folgende Beispiel zeigt die
verschiedenen Möglichkeiten:
19
Einführung in den Mikrocontroller 80C517A
konstante1:
konstante2:
konstante3:
DB
DB
DB
'a','b','c'
97,98,99
'abc'
;als Zeichen
;als ASCII-Werte
;als String
Die DW-Direktive initialisiert Codespeicher mit 16bit Words.
Die DBIT-Direktive
Die DBIT-Direktive reserviert Speicher in einem Bit-Segment.
flag:
DBIT
1
;reserviert Speicher für ein Bit
Die ORG-Direktive
Die ORG-Direktive (Origin) wird verwendet, um Programmcode ab einer bestimmten
Adresse im Speicher starten zu lassen.
ORG
adresse
Trifft der Assembler auf eine ORG-Anweisung, übernimmt er den Wert und ordnet dem
folgenden Befehl die genannte Adresse zu.
Die END-Direktive
Die END-Direktive kennzeichnet das Ende des Quelltextes. Alle nachfolgenden Befehle
werden ignoriert.
END
3.2 Der Stack
Der Stapelspeicher (Stack) ist ein in seiner Größe limitierter Speicherbereich, der 8bit breit
organisiert ist. Auf ihn kann nur mit dem Stapelzeiger (SP), einem ebenfalls 8bit breiten
Register, zugegriffen werden. Er wird hauptsächlich beim Aufruf von Unterprogrammen und
Interruptroutinen benötigt, kann aber auch zur temporären Speicherung von Registern
verwendet werden.
Der Stack arbeitet nach dem LIFO-Prinzip (Last In First Out), d.h. es kann immer nur auf das
zuletzt auf den Stack gelegte Register zugegriffen werden. Für Stackoperationen stehen die
beiden Befehle PUSH und POP zur Verfügung.
PUSH
POP
ACC
ACC
Der Befehl PUSH inkrementiert den Stapelzeiger und rettet den Akkumulator auf den Stack.
Der POP-Befehl holt den gespeicherten Wert wieder vom Stack und dekrementiert
anschließend den Stapelzeiger, so daß dieser stets auf den obersten Wert des Stapelspeichers
zeigt. Die Befehle PUSH und POP verlangen als Operatoren die absoluten Adressen der
Register. Diese lauten
20
Einführung in den Mikrocontroller 80C517A
ACC
AR0
ARx
für den Akkumulator
für das Register R0
für die Register Rx
Bei einem Interrupt wird beispielsweise vor der Ausführung der Interruptroutine die
Rücksprungadresse auf den Stack gesichert, an der das Programm nach Abarbeitung der
Routine wieder fortgeführt wird. Zusätzlich müssen alle Register, die in dieser Routine
verändert werden, beim Eintritt in die ISR auf den Stack gesichert werden, da der Interrupt
das Hauptprogramm jederzeit unterbrechen kann. Vor dem Rücksprung in das
Hauptprogramm müssen die Register wieder restauriert werden.
Für den Stapelspeicher muß ein ausreichend großer Speicherbereich im internen RAM
reserviert werden. Dies geschieht folgendermaßen:
STACK
SEGMENT IDATA
RSEG
STACK
DS
20h
;Stacksegment definieren
;32 Byte für Stapelspeicher reservieren
Der Stapelzeiger wird zu Beginn des Hauptprogramms mit folgender Befehlszeile initialisiert,
so daß der erste Push-Befehl den Wert an den Anfang des reservierten Speicherbereiches legt:
start:
mov
SP,#STACK-1
3.3 Programmstrukturen
Programmverzweigungen
Programmverzweigungen werden mit den Sprungbefehlen des Mikrocontrollers realisiert. Er
unterscheidet dabei zwischen unbedingten und bedingten Sprüngen. Mit den unbedingten
Sprüngen ACALL und AJMP kann nur innerhalb eines 2kByte-Adreßbereiches verzweigt
werden, während die Sprungbefehle LCALL und LJMP den gesamten Speicher adressieren
können. Zur Steuerung des Programmablaufs besitzt der Mikrocontroller die bedingten
Sprungbefehle. Die folgenden Beispiele zeigen die Umsetzung von typischen
Programmstrukturen in Assembler-Code.
Eine If-Anweisung läßt sich in Assembler folgendermaßen realisieren:
IF-Anweisung
if (Akku > 0) then
zaehler = zaehler+1
analoge Assembler-Routine
jz
inc
weiter
zaehler
weiter:
Beispiel 1 IF-Anweisung
21
Einführung in den Mikrocontroller 80C517A
Ist die Bedingung (Akku > 0) nicht erfüllt, wird ein Sprung zu der durch das Label weiter
angegebenen Adresse durchgeführt, ansonsten wird mit der Abarbeitung des nächsten Befehls
fortgefahren.
IF (AND-Verknüpfung)
if (Akku > 0) and (R0 = 1)
analoge Assembler-Routine
jz
then
cjne
zaehler = zaehler+1
inc
weiter
R0,#1,weiter
zaehler
weiter:
Beispiel 2 AND-Verknüpfung
Bei der logischen AND-Verknüpfung wird zum Label weiter verzweigt, wenn mindestens
eine der beiden Bedingungen (Akku > 0) oder (R0 = 1) nicht erfüllt ist. Andernfalls wird die
Variable zaehler um eins erhöht.
IF (OR-Verknüpfung)
if (Akku > 0) or (R0 = 1)
then
zaehler = zaehler+1
analoge Assembler-Routine
jz
jmp
bed2
incr
bed2:
cjne
R0,#1,weiter
incr:
inc
zaehler
weiter:
Beispiel 3 OR-Verknüpfung
Die logische OR-Verknüpfung wird implementiert, indem zuerst die Bedingung (Akku > 0)
geprüft wird. Ist diese erfüllt, erfolgt sofort der Sprung zum Label incr und die Variable
zaehler wird erhöht. Ist sie nicht erfüllt, wird die zweite Bedingung (R0 = 1) geprüft und bei
Übereinstimmung zum Label incr verzweigt. Eine If-Else-Anweisung besitzt in Assembler
folgende Struktur:
IF-ELSE-Anweisung
if (Akku > 0) then
zaehler = zaehler+1
else zaehler = zaehler-1
analoge Assembler-Routine
jz
decr
inc
zaehler
jmp
weiter
decr:
dec
weiter:
Beispiel 4 IF-ELSE-Anweisung
22
zaehler
Einführung in den Mikrocontroller 80C517A
Eine For-Schleife wird mit dem Assemblerbefehl djnz gelegt. Dieser Befehl dekrementiert das
angegebene Register und prüft es anschließend auf Null. Ist es ungleich Null, wird das Label
schleife angesprungen.
FOR-Schleife
analoge Assembler-Routine
mov
for i = N downto 1 do
R0,#N
schleife:
begin
anweisung1
...
anweisung2
...
...
djnz
R0,schleife
end
Beispiel 5 FOR-Schleife
Das letzte Beispiel zeigt eine While-Struktur. Die While-Schleife wird erst dann verlassen,
wenn die Bedingung (Akku > 0) nicht mehr erfüllt ist.
WHILE-Schleife
Analoge Assembler-Routine
while (Akku > 0) do
loop:
Akku = Akku-1
jz
weiter
dec
A
jmp
loop
weiter:
Beispiel 6 WHILE-Schleife
Interrupt-Zählvariablen
Um Zeiten messen zu können, die größer sind als die Umlaufzeit eines Referenzzählers, ist es
notwendig, die Anzahl der Timerüberläufe softwaremäßig mitzuzählen.
Tges = t2 – t1 sei die Zeit, nach welcher die ISR abgearbeitet werden soll. Um die Anzahl der
Timerüberläufe mitzuzählen, wird eine Variable angelegt, die bei jedem Interruptaufruf
heruntergezählt wird. Ist diese Variable gleich 0, dann wird die ISR abgearbeitet, ansonsten
wird zum Ende der Routine gesprungen. Die Zeitdauer ist dann durch folgende Formel
bestimmt:
T ges = ( Z 2 − Z 1 + Ü ∗ 2 Z ) ∗
1
f Timer
Ü = Anzahl der ermittelten Überläufe
Z = Zählerbreite des Referenzzählers in Bit
Z1 = Zählregisterinhalt zum Zeitpunkt t1
Z2 = Zählregisterinhalt zum Zeitpunkt t2
23
Einführung in den Mikrocontroller 80C517A
3.4 Ausmaskierung von Bits
In Spezialfunktionsregistern werden häufig nur bestimmte Bits verändert, während die
restlichen Bits nicht beeinflußt werden dürfen. Bits, die sich in bitadressierbaren
Spezialfunktionsregistern befinden, können mit den Assemblerbefehlen setb und clr
gesetzt bzw. gelöscht werden. Bei SFRs, die nicht bitadressierbar sind, müssen die Bits durch
die logischen AND- und OR-Verknüpfungen ausmaskiert werden.
Bits in einem Byte werden gelöscht, indem das Byte mit einer Maske AND-verknüpft wird, in
der an den Bitpositionen der zu löschenden Bits Nullen stehen. Die Bitpositionen, die sich
nicht verändern sollen, enthalten eine eins.
Im folgenden Beispiel werden die obersten zwei Bits gelöscht.
&
11111001
00111111

00111001
Byte
Maske
Bits in einem Byte werden gesetzt, indem das Byte mit einer Maske OR-verknüpft wird, in
der die Bitpositionen der zu setzenden Bits eine eins enthalten. Im nächsten Beispiel werden
die unteren drei Bits gesetzt.
∨
10110010
00000111

10110111
Byte
Maske
3.5 Softwareerstellung
Die Erstellung des Programmcodes gliedert sich in drei Schritte:
1. Der Assembler
Im ersten Schritt wird der Programmcode in einer Quelldatei mit der Endung (.a51) editiert.
Der Assembler A51 übersetzt diesen Quellcode in einen Objektcode. Er erzeugt eine
Objektdatei (.obj) und eine Listingdatei (.lst), in der die Ergebnisse der Assemblierung
protokolliert werden. Die Objektdatei ist relokatibel, d.h. es werden noch keine absoluten
Adressen für den Programmcode erzeugt.
2. Der Linker
Der Linker/Locater L51 bindet mehrere Programm-Module, die als Objektdateien vorliegen,
zu einem ablauffähigen Programm zusammen. Dabei werden Extrn/Public-Bezüge aufgelöst
24
Einführung in den Mikrocontroller 80C517A
und die relokatiblen Programmteile auf absolute Adressen plaziert. Die zu kombinierenden
Module können sowohl in Assembler als auch in der Programmiersprache C geschrieben sein.
Der Linker ermöglicht eine modulare Programmierung, d.h. die Zerlegung des Quellcodes in
mehrere Module. Dadurch bleibt auch ein sehr großes Programm übersichtlich.
Der Linker erzeugt eine absolute Objektdatei (.abs) und eine Map-Datei (.m51), die die
Ergebnisse des Link-Prozesses enthält.
3. Der Objekt-Hex-Konverter
Der Programmcode, der sich in der Objektdatei befindet, wird in Hexadezimalwerte
konvertiert und im Intel-HEX-Dateiformat ausgegeben. Die HEX-Datei kann von EPROMProgrammiergeräten oder von den im Praktikum verwendeten Flashtools in den Speicher des
Mikrocontrollers geschrieben werden. Abbildung 7 zeigt den Ablauf der QuellcodeErstellung.
Abbildung 7 Programmerstellung für den 80C517A
25
Einführung in den Mikrocontroller 80C517A
3.6 Das Entwicklungstool Proview
Zur Erstellung der Assemblerprogramme für die Versuchsaufgaben wird das Softwaretool
Proview verwendet. Es unterstützt das Compilieren, Assemblieren und Linken von
Quellcode-Dateien in einem Projekt. Ein Projekt gliedert sich in mehrere Dateien, die beim
Linken zu einer Objektdatei zusammengefügt werden. Ein in Proview integrierter Simulator
ermöglicht es, die erstellten Programme zu testen und erleichtert die Fehlersuche erheblich.
Der Umgang mit Proview soll anhand eines Beispiels demonstriert werden:
•
Öffnen Sie mit „Project|Open“ das Projekt beispiel.prj im Verzeichnis c:\beispiel. Es
erscheint das Projektfenster. Klicken Sie mit der rechten Maustaste auf das
Projektfenster und wählen Sie „Add file“. Fügen Sie dem Projekt auf diese Weise die
Module cpuinit.c, delay.a51, lcd.c und led.c sowie das Hauptprogramm main.c hinzu.
•
Compilieren und Linken Sie das Projekt mit „Project|Build all“. Proview erstellt die
Zwischencode-Dateien (.obj) und die Listingdateien (.lst) nach Abbildung 7. Die
benötigte Datei im Intel-Hex-Format wird automatisch miterzeugt. Ein Message-Fenster
gibt Auskunft über den Compilier- und Linkprozeß.
•
Der Programmcode, der nun als Intel-Hex-Datei vorliegt, kann mit Hilfe der Flashtools
der Firma Phytec über die RS-232-Schnittstelle des PC in den Flashspeicher des
Mikrocontrollers geladen werden. Der Flashspeicher besteht aus 2 Bänken à 64 KB, die
wiederum in 4 Sektoren unterteilt sind. Die erste Bank (Bank 0) ist schreibgeschützt, da
sich in ihr die Firmware befindet, die für die Kommunikation mit dem PC zuständig ist.
Die zweite Bank ist unbelegt, in sie wird der Programmcode geladen. Der
Mikrocontroller bootet nach einem Hardware-Reset stets aus dieser Bank. Gehen Sie ins
Menü „Tool|Run Tool|Flash“ und starten Sie die Flashtools.
•
Quittieren Sie die folgende Meldung mit „o.k.“. Bevor eine Kommunikation mit dem
Mikrocontroller aufgebaut werden kann, müssen Sie diesen zuerst in den
Programmiermodus bringen. Dies geschieht, indem Sie die Programmiertaste an der
Frontplatte des Gehäuses gedrückt halten und anschließend den Reset-Knopf für ca. 2s
betätigen. Der Programmiermodus wird durch vier leuchtende LEDs angezeigt.
•
Jetzt können Sie den Download des Programms starten. Wenn die Übertragung beendet
ist, können Sie die Flashtools verlassen. Das Programm befindet sich nun im Speicher
des Mikrocontrollerboards und kann durch Betätigung der Reset-Taste (ca. 2s) gestartet
werden. Es bleibt auch nach Abschalten der Spannungsversorgung erhalten.
Den integrierten Debugger von Proview starten Sie durch den Aufruf von „Debug|Start“.
Wählen Sie „Virtual Machine (Simulator)“ und geben Sie unter Mikrocontroller „80C517“
und unter Frequency „18 MHz“ an. Nun können Sie Ihr Programm starten, indem Sie auf das
Symbol „GO“ klicken. Der Debugger beginnt mit der Abarbeitung des Programms an der
Adresse, die im Register PC steht. Mit „Step into“ und „Step over“ kann das Programm Zeile
für Zeile abgearbeitet werden oder es können Breakpoints gesetzt werden. Dabei können Sie
sich über das Menü „View“ sämtliche Registerwerte, den Inhalt des Daten- und
Programmspeichers und den Status der einzelnen Peripherieeinheiten anzeigen lassen. Sie
26
Einführung in den Mikrocontroller 80C517A
haben die Möglichkeit, den Inhalt der CPU-Register und des internen Speichers zu editieren.
Die Funktion „Add Watch“ im Menü „Debug“ ermöglicht die Überwachung von
Programmvariablen. Mit „Reset“ im gleichen Menü läßt sich ein Hardware-Reset simulieren.
Danach kann das Programm erneut gestartet werden.
Den Debugger verlassen Sie mit „Debug|Terminate“.
Abbildung 8 Der Simulator von Proview
27
Einführung in den Mikrocontroller 80C517A
4
Anhang
Vektoradresse
Interruptquelle
Request-Flag
00ABh
Compare match COMCLR
ICR
00A3h
Compare match COMSET
ICS
009Bh
Compare-Timer Overflow
CTF
0093h
Compare match CM0-CM7
ICMP0 - ICMP7
0083h
serieller Port Interrupt 1
RI1/TI1
006Bh
externer Interrupt 6
IEX6
0063h
externer Interrupt 5
IEX5
005Bh
externer Interrupt 4
IEX4
0053h
externer Interrupt 3
IEX3
004Bh
externer Interrupt 2
IEX2
0043h
A/D-Wandler-Interrupt
IADC
002Bh
Überlauf Timer 2
TF2+EXF2
0023h
Serieller Port Interrupt 0
RIO+TIO
001Bh
Timer 1 Interrupt
TF1
0013h
externer Interrupt 1
IE1
000Bh
Timer 0 Interrupt
TF0
0003h
externer Interrupt 0
IE0
0000h
Reset
Abbildung 9 Die Interrupt-Vektoradressen des SAB80C517A
28
Einführung in den Mikrocontroller 80C517A
Code
Instructions
Description
Execution time
RS R/W DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
Clears all display and returns the
Clear display
0
0
0
0
0
0
0
0
0
1 cursor to the home position
82 µs ~ 1.64 ms
(Address 0).
Returns the cursor to the home position (Address 0). Also returns the
Return home
0
0
0
0
0
0
0
0
1
-
display being shifted to the original
40 µs ~ 1.6 ms
position. DD RAM contents remain
unchanged.
Sets the cursor move direction and
Entry mode set
0
0
0
0
0
0
0
1
I/D
S
specifies or not to shift the display.
40 µs
These operations are performed
during data write and read.
Sets ON/OFF of all display (D),
Display ON/OFF control
0
0
0
0
0
0
1
D
C
B cursor ON/OFF (C), and blink of
40 µs
cursor position character (B).
Moves the cursor and shifts the
Cursor and display shift
0
0
0
0
0
1 S/C R/L
-
-
display without changing DD RAM
40 µs
contents.
Sets interface data length (DL) numFunction set
0
0
0
0
1
DL
N
F
-
-
ber of display lines (L) and character
40 µs
font (F).
Sets the CG RAM address. CG RAM
Set CG RAM address
0
0
0
ACG
1
data is sent and received after this
40 µs
setting.
Sets the DD RAM address. DD RAM
Set DD RAM adress
0
0
1
ADD
data is sent and received after this
40 µs
setting.
Reads Busy flag (BF) indicating interRead busy flag & address
0
1
BF
AC
nal operation is being performed and
40 µs
reads address counter contents.
Write data to CG or DD RAM
1
0
Write Data
Writes data into DD RAM or CG
40 µs
RAM.
Read data to CG or DD RAM
1
1
Read Data
Reads data from DD RAM or CG
40 µs
RAM.
I/D = 1: Increment
S = 1:
I/D = 0: Decrement
Accompanies display shift.
DD RAM: Display data RAM
CG RAM: Character generator RAM
S/C = 1: Display shift S/C = 0: Cursor move ACG:
CG RAM address
ADD:
DD RAM address
R/L = 1: Shift right
R/L = 0: Shift left
DL = 1: 8 bits
DL = 0: 4 bits
corresponds to cursor
N = 1:
2 lines
N = 0:
1 line
address.
F = 1:
5x10 dots
F = 0:
5x7 dots
AC:
Address counter used for
BF = 1: Internally operating
both DD and CG RAM
BF = 0: can accept instruction
address.
Abbildung 10 Befehle des Grafikcontrollers
29
Einführung in den Mikrocontroller 80C517A
Abbildung 11 Zeichensatz des LCD
30
Einführung in den Mikrocontroller 80C517A
;*********************************************************************************
;*
Programmrahmen für ein Hauptprogramm, das auf dem Mikrocontroller 80C517A
*
;*
laufen soll. Die Datei ´REG517A.INC´, die die Registernamen des 80C517A
*
;*
enthält, muß bei der Assemblierung im aktuellen Verzeichnis stehen.
*
;*
Kommentare beginnen mit einem Semikolon. Alles, was danach folgt, wird
*
;*
beim Assemblieren ignoriert. Labels, die das Hauptprogramm aus anderen
*
;*
Modulen verwendet, werden mit der Direktive EXTRN eingebunden. Die Module
*
;*
müssen zuvor dem Projekt hinzugefügt werden. Text, der kursiv dargestellt
*
;*
ist, muß entsprechend ergänzt werden.
*
;*********************************************************************************
$NOMOD51
;Registerbelegung des 8051 abschalten
$include(REG517A.INC)
;SFR Symbole von 80517A benutzen
NAME
<Hier muß der Name des Programms stehen>
;*********************************************************************************
;*
Extern-Definitionen
*
;*********************************************************************************
EXTRN
CODE(delay)
;Modul delay.a51
<Hier können weitere Labels stehen, auf die das Hauptprogramm zugreift und die
sich in einem anderen Modul befinden>
;*********************************************************************************
;*
Segment-Definitionen
*
;*********************************************************************************
PROG
SEGMENT CODE
;Codesegment definieren
STACK
SEGMENT IDATA
;Stacksegment definieren
VAR
SEGMENT DATA
;Datensegment definieren
BITS
SEGMENT BIT
;Bitsegment definieren
using 0
;Registerbank 0 auswählen
;*********************************************************************************
;*
Konstanten-Deklaration
*
;*********************************************************************************
<Hier werden die benutzten Konstanten mittels der EQU-Direktive definiert>
;*********************************************************************************
;*
Stack-Segment
*
;*********************************************************************************
RSEG
STACK
DS
20h
;32 Byte für Stapelspeicher reservieren
;*********************************************************************************
;*
Variablen-Deklaration
*
;*********************************************************************************
RSEG
VAR
<Hier kann Platz für die notwendigen Variablen reserviert werden>
;*********************************************************************************
;*
absolute Segmente
*
;*********************************************************************************
CSEG AT 0000h
;Startadresse nach einem Hardware-Reset
ljmp start
CSEG AT <Interruptvektoradresse>
;Einfügen einer Interruptserviceroutine
<Hier steht der Sprungbefehl zur eigentlichen ISR>
;*********************************************************************************
;*
Code-Segment
*
;*********************************************************************************
RSEG
PROG
ORG
0100h
start:
mov
SP,#STACK-1
;Stack initialisieren
<Hier beginnt das Hauptprogramm>
END
Listing 1 Programmrahmen für ein Hauptprogramm
31
Einführung in den Mikrocontroller 80C517A
;*********************************************************************************
;*
Programmrahmen für ein Unterprogramm, das auf dem Mikrocontroller 80C517A
*
;*
laufen soll. Die Datei ´REG517A.INC´, die die Registernamen des 80C517A
*
;*
enthält, muß bei der Assemblierung im aktuellen Verzeichnis stehen.
*
;*
Kommentare beginnen mit einem Semikolon. Alles, was danach folgt, wird
*
;*
beim Assemblieren ignoriert. Labels, die das Unterprogramm für das Haupt*
;*
programm bereitstellt, müssen mit der Direktive PUBLIC bekannt gemacht
*
;*
werden. Text, der kursiv dargestellt ist, muß entsprechend ergänzt werden. *
;*********************************************************************************
$NOMOD51
;Registerbelegung des 8051 abschalten
$include(REG517A.INC)
;SFR Symbole von 80517A benutzen
NAME
<Hier muß der Name des Unterprogramms stehen>
;*********************************************************************************
;*
Public-Definitionen
*
;*********************************************************************************
PUBLIC <Hier müssen die Labels eingetragen werden, die für andere Module
bekannt gemacht werden sollen>
;*********************************************************************************
;*
Segment-Definitionen
*
;*********************************************************************************
PROG
SEGMENT CODE
;Codesegment definieren
VAR
SEGMENT DATA
;Datensegment definieren
BITS
SEGMENT BIT
;Bitsegment definieren
using 0
;Registerbank 0 auswählen
;*********************************************************************************
;*
Konstanten-Deklaration
*
;*********************************************************************************
<Hier werden die benutzten Konstanten mittels der EQU-Direktive definiert>
;*********************************************************************************
;*
Variablen-Deklaration
*
;*********************************************************************************
<Hier kann Platz für die notwendigen Variablen reserviert werden>
;*********************************************************************************
;*
Code-Segment
*
;*********************************************************************************
RSEG
PROG
<Hier beginnt der Programmcode der Unterroutine>
END
Listing 2 Programmrahmen für ein Unterprogramm
32
Was this manual useful for you? yes no
Thank you for your participation!

* Your assessment is very important for improving the work of artificial intelligence, which forms the content of this project

Download PDF

advertisement