Edit v5.011 from 2005-01-21 to 2024-07-25 by HSc
Microcontroller 8051
Hier erfahren Sie genaueres über die uns bekannte Ausstattung des Microcontrollers 8051 mit seiner Hard- und Software. Diese dienen als Grundlage für alle weiteren Projekte mit dem MC8051 die bei uns vorgestellt werden.
Werkzeuge
Um ein lauffähiges Programm zu erstellen, sind die im folgende beschriebenen Werkzeuge nützlich!
Entwicklungsumgebung
Diese kann alle Werkzeuge enthalten und
in der benötigten Reihenfolge aufrufen.
Das spart viel Tip-Arbeit und Zeit.
Bei uns ist daß das Betriebssystem MS−DOS und
eine Batch-Datei,
welche die Werkzeuge in der Reihnenfolge Editor, Assembler, Loader und
Terminalprogramm aufruft!
Elektro liefert mit seinem EASM51 auch den Loader,
das Terminalprogramm und
ein Menüprogramm zum komfortablen Aufruf
der selbigen mit.
Editor
Ein Editor, um das Programm (????????.A51) zu schreiben und
welche unter DOS lauffähig ist!
Welches ist Ihr Lieblings-Texteditor?
Den sollten sie einsetzen.
Bei uns ist dies der Norton Editor NED.COM,
da er trotz seiner kleinen Größe alles minimal Notwendige
enthält.
Den Namen der Datei (EQU02.A51) kann er aus dem Übergabeparameter
entnehmen.
NED.COM EQU02.A51
Assembler
Ein Assembler, um die mit dem Editor geschriebene Mnemonik, auf deren richtige Schreibweise zu überprüfen und wenn diese gültig ist, eine Listing-Datei erstellt und des Weiteren ihn in ein Intel−Hex−File übersetz.
Wir benutzen hier den Elektro Assembler EASM.EXE mit dem Aufruf
EASM.EXE EQU02.A51
Terminalprogramm
Das Terminalprogramm stelle die Verbindung zwischen Computer und dem Microcontroller, über die serielle Schnittstelle, her. Die in Ihm gemachte Eingaben verarbeitet er und kommuniziert entsprechend mit dem Microcontroller. So gibt er die vom Microcontroller versandten Zeichen auf den Bildschirm des Computers aus. Elektro lieferte mit seinem 8051er-System das Terminalprogramm V24COM.EXE mit. Diese erwartet als Übergabeparameter den Namen des Intel−Hex−Files und den Namen der seriellen Schnittstelle.
V24COM.EXE EQU02.HEX -COM1
Das 1. Programm
Wenn diese grundsätzliche Notwendigkeit nicht geklärt ist und
funktioniert,
kann der Rest vergessen werden.
Denn Übung macht den Meister!
Wir haben uns für den Norton-Editor,
den 8051−Assembler von Elektor EASM51 und dessen
Transferprogramm V24COM.EXE entschieden.
Im ersten Programm wollen wir den Befehl EQU (equal zu Deutsch gleich)
ausprobieren
Der Quelltext
Der Inhalt dieses Quelltextes
;*************************************************************** ;* Zuweisung eines Namens "P1" zur Adresse "90H", * ;* wo Port 1 liegt. * ;* Frage: * ;* - Wie sind die Auswirkung auf die Listing-Datei? * ;* Ziel: * ;* - Wenn alles geklappt hat und * ;* nach einem Reset das Programm auf den Microcontroller * ;* ausgefuehrt wird, * ;* sollten sich einige Bits am Port 1 von 0 auf 5 Volt und * ;* umgekehrt aendern. * ;* =========================================================== * ;* Copyright by Hilfe & Service von EDV-Fachleuten * ;* Reilstr. 6, D-06114 Halle (Saale) * ;* Tel. (0345) 521 13 40 * ;* Fax (0345) 521 13 41 * ;* eM Info@HuSvEDVF.de * ;* Edit v1.010 from 2006-01-12 to 2011-06-10 by HSc * ;* ----------------------------------------------------------- * ;* Input * ;* Process * ;* + Constant * ;* - P1 = 90H, die Adresse des Port Eins. * ;* + Variable * ;* Output * ;*************************************************************** ;******* Definition von Konstanten ***************************** P1 EQU 90H ;******* Hauptprogramm ***************************************** ORG 04100H ;Programm steht ab 4100H MOV P1,#15 ;Lade auf die Adresse ;vom Port 1 die 15 RET ;Ende des Hauptprogramms END ;Ende des Programms ;******* EOF ***************************************************
Wenn alles geklappt hat, sollte das Ziel erreicht worden sein.
Die Umsetzung
Wie sind wir vorgegangen, um ein Programm zu erstellen, zu testen und es auf dem Zielsystem laufen zu lassen? Dazu ist als Entwicklungsumgebung ein Computer mit einem DOS−Betriebssystem notwendig, wo das Programm erstellt, assembliert (Übersetzt) und über die serielle Schnittstelle eine Verbindung zum MC8051-Board hergestellt und damit das HEX-File übertragen werden kann; In dieser Entwicklungsumgebung sind zur Überführung in ein lauffähiges Programm 4 bis maximal 5 Schritten notwendig.
-
Erstellen bzw. Editieren des Quelltextes mit einem Editor.
NED.COM EQU02.A51
Wir setzen hier den Norton Editor ein. -
Assemblieren
zum Überpürfen des Quelltextes auf
Fehlerfreiheit und Umwandeln dessen in das
Intel-Hex-Format (*.HEX)
plus der Ausgabe des Quelltextes in Form einer
Listingdatei (*.LST).
EASM.EXE EQU02.A51
Ist der Quelltext syntaktisch nicht fehlerfrei, wird auf die entsprechende Zeile verwiesen. Dann ist eine Korrektur mittels Editor angesagt. -
Übertragung
der Intel-Hex-Datei über die serielle Schnittstelle 1
zum MC8051-Board,
wo es vom Monitorprogramm empfangen und
entsprechend der Angaben in der Datei abgespeichert wird;
V24COM.EXE EQU02.HEX -COM1
- Ausführen des erstellten Programms durch seinen Aufruf an der Konsole des MC5051-Board's.
- Debuggen bzw. Analysieren ist mit dem Monitor−Programm des MC8051−Board möglich.
Das Ergebnis
Nach Aufruf des Befehlesdir EQU02.*erhält man folgende Dateien aufgelistet:
-
EQU02.A51
= Der eingegebenen Quellcode; -
EQU02.LST
= Vom Assembler erstelle Listing-Datei mit Zusatzinformationen; -
EQU02.HEX
= Das vom Assembler erstellte Programm im Intel-Hex-Format.
Lektionen
- Vorstellung vom Aufbau eines Quelltextes,
- über Konstanten und Variablen,
- Speichermanipulationen,
CPU | A | B | SP | PC | DPTR | |||
---|---|---|---|---|---|---|---|---|
8051 | 15 | xx | 81 | 4202 | xxxx | |||
PSW | CV | AC | F0 | RS1 | RS0 | OV | F1 | P |
D0 | x | x | x | x | x | x | x | x |
Bank | R0 | R1 | R2 | R3 | R4 | R5 | R6 | R7 |
00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 |
SP | +00 | +01 | +02 | +03 | +04 | +05 | +06 | +07 |
03 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 |
SFR | ||||||||
88H = TSCON 89H = TMOD 98H = SCON |
00H = 0000 0000B 00H = 0000 0000B 00H = 0000 0000B |
|||||||
Code | ||||||||
4200 74 15 [1]: MOV A,#15H 4202 F5 70 [1]> MOV 70H,A 4204 22 __ [2]: RET |
- In dem ersten Zeilenpaar den Derivat-Namen der CPU, wichtig da jedes Derivat andere Möglichkeiten (Ports's, A/D-Wandler, etc.) besitzt. Des Weiteren den Inhalt der Arbeitsregister A und B, sowie den Stack-Pointer SP, Program-Counter PC und den Daten-Pointer DPTR.
-
Im mittleren Zeilenpaar ist das Program-Status-Word,
welches eine entscheidende Rolle bei den bedingten Sprüngen spielt,
mit seinen Bit's
- Carry−Flag CV,
- Half-Carry-Flag AC,
- Register−Bank−Bit 0 RS0 und 1 RS1,
- OV,
- F1 und
- Paritäts−Bit P bzgl. des Inhaltes vom Akkumulator.
- Im letzten Zeilenpaar ist die Differenz zwischen Startwert und aktuellen Wert im Stackpointer SP zu sehen. Oder anders ausgedrückt, die Anzahl der auf dem Stack abgelegten Bytes. Daneben sind die alle abgelegten Bytes aufgelistet und durch nummeriert.
- Einen Auszug aus der Liste der Spezial-Funktions-Register SFR, die für die Abarbeitung der unmittelbaren folgenden Befehls von Bedeutung sind.
CPU | A | B | SP | PC | DPTR | PSW | CV | AC | F0 | RS1 | RS0 | OV | F1 | P | ||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
8051 | 15 | xx | 81 | 4202 | xxxx | D0 | x | x | x | x | x | x | x | x | ||||
Bank | R0 | R1 | R2 | R3 | R4 | R5 | R6 | R7 | SP | +00 | +01 | +02 | +03 | +04 | +05 | +06 | +07 | |
00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 03 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | |
Code | SFR | |||||||||||||||||
4200 74 15 [1]: MOV A,#15H 4202 F5 70 [1]> MOV 70H,A 4204 22 __ [2]: RET |
88 = TSCON 89 = TMOD 98 = SCON |
00 = 0000 0000B 00 = 0000 0000B 00 = 0000 0000B |
0. Grundlagen
- Das 1. Programm incl. seiner Kommentare.
- Grundsätzliche Struktur des Quelltextes mit möglichen Inhalt bzgl. Speichermodel, Prozessormodel, Beginn und Ende.
- Konstanten, Variablen, Marken und deren Verwendung.
- Deklarieren von Funktionen und Prozeduren, und deren Aufruf und Nutzung.
1. Befehlsbeispiele
2. Konsole
3. Interrupt
4. Keyboard Video Mouse
- Zahlen,
- Texten,
- Datum,
- Uhrzeit und
Befehls-Code
Flags
Mnemonik
- Datentransfer, mit grünen Hintergrund,
- Arithmetischen, mit roten Hintergrund,
- Logischen, mit gelben Hintergrund, und
- Sprung Operationen, mit blauen Hintergrund.
Teileweise gibt es eine Verweis zu einer Lektion, wo der Befehl eingesetzt wurde und um seine Funktion schneller verstehen zu können.
Vorab einige Erläuterungen zu den verwendeten Abkürzungen:- @
- Indirekte Adressierung, d.h. nicht der Inhalt verweist auf das Ziel, sondern der Inhalt verweist auf eine Adresse, welche dann auf das Ziel verweist;
- adr08 und adr16
- Absolute 8- und 16 Bit große Adresse; um auf deren Daten zuzugreifen;
- badr
- Absolute Adresse von 0 bis 127, welche auf ein Bit verweist im Adressbereich von 20H bis 2FH. 0 bis 127 Bits entspricht einem Speicherbereich von 20H plus 0/8=00H bis 127/8=0FH Bytes;
- #c08 und #c16
- Konstanten mit einer Größe von 8 und 16 Bit;
- radr08
- Relativen 8 Bit-Adresse mit einen Bereich von -128, …, +127 Bytes. Dies entspricht einer Größe von 8 Bit im Zweierkomplement.
- Ri
- Eines von den R0 und R1 Registern;
- Rr
- Eines von den R0 bis R7 Registern;
Datentransfer
Mnemonik und Befehl-Code | Zyklen | Beschreibung mit Verweis auf ein Beispiel |
---|---|---|
1 Befehl zum nichts tun (no operation) | ||
NOP 00 |
1 | Es wird nichts getan, außer Zeit verbraucht. Dies kann manchmal wichtig sein, beim Warten und Zeitmessungen. |
Die 4+2+2 Befehle mit MOV A,… bzw. MOVC A,… bzw. MOVX A,… | ||
MOV A,adr08 E5 ?? |
1 | Kopiere den Inhalt der RAM-Adresse "adr08=??H" in den Akkumulator. Da die Adresse mittels eines Bytes beschrieben wird, reicht diese von Null (00H) bis 255 (0FFH)! |
MOV A,#c08 74 ?? |
1 | Trage den 8 Bit-Wert "#c08=??H" in den Akkumulator ein. |
MOV A,Rr E8/E9/EA/EB/EC/ED/EE/EF |
1 | Kopiere den Inhalt des Registers r=(0, 1, 2, 3, 4, 5, 6, 7) in den Akkumulator. |
MOV A,@Ri E6/E7 |
1 | Kopiere den Inhalt der 8 Bit-RAM-Adresse, welche im Register i=(0, 1) steht, in den Akkumulator. |
MOVC A,@A+DTPR 93 |
2 | Kopiere den Inhalt der externen 16 Bit-RAM-Adresse, welche sich aus der Addition vom Daten-Pointer und Akkumulator ergibt, in den Akkumulator und überschreibt damit diesen. |
MOVC A,@A+PC 83 |
2 | Kopiere den Inhalt der externen 16 Bit-RAM-Adresse, welche sich aus der Addition vom Programm-Counter und Akkumulator ergibt, in den Akkumulator und überschreibt damit diesen. |
MOVX A,@DPTR E0 |
2 | Kopiere den Inhalt der externen 16 Bit-RAM-Adresse, welche im Daten-Pointer steht, in den Akkumulator. |
MOVX A,@Ri E2/E3 |
2 | Kopiere den Inhalt der externen 8 Bit-RAM-Adresse, welche im Register i=(0, 1) steht, in den Akkumulator. |
Die 5 Befehle mit MOV adr08, … | ||
MOV adr08a,A F5 ?? |
1 | Kopiere den Inhalt des Akkumulators an die 8 Bit-RAM-Adresse "adr08a=??". |
MOV adr08a,adr08b 85 ?? ?? |
2 | Kopiere den Inhalt der 8 Bit-RAM-Adresse "adr08b=??" an die Stelle der 8 Bit-RAM-Adresse "adr08a=??". |
MOV adr08a,#c08 75 ?? ?? |
2 | Trage den 8 Bit-Wert "#c08" in die 8 Bit-RAM-Adresse "adr08a" ein. |
MOV adr08a,Rr 88 ??/89 ??/8A ??/8B ??/ 8C ??/8D ??/8E ??/8F ?? |
2 | Kopiere den Inhalt des Registers r=(0, 1, 2, 3, 4, 5, 6, 7) an die 8 Bit-RAM-Adresse "adr08a". |
MOV adr08a,@Ri 86 ??/87 ?? |
2 | Kopiere den Inhalt der 8 Bit-RAM-Adresse "adr08", welche im Register i=(0, 1) steht, an die RAM-Adresse "adr08a". |
Die 1+1 Befehle mit MOV und Carry-Flag | ||
MOV badr,C 92 ?? |
2 | Kopiert den Wert des Carry-Flags auf die Stelle, auf welche die Bit-Adresse "badr" verweist. |
MOV C,badr A2 ?? |
1 | Kopiert den Wert auf welche die Bit-Adresse "badr" verweist in das Carry-Flag. |
Der 1 Befehl mit MOV DPTR, … | ||
MOV DPTR,#data16 90 ?? ?? |
2 | Beschreibt den Daten-Pointer mit einer 16 Bit-Konstante "data16". Der Daten-Pointer verweist dann, auf eine Stelle im externen Datenspeicher, welcher mit der Adresse übereinstimmt, welche durch die 16 Bit-Konstante gebildet wurde. |
Der 1 Befehl mit MOVX @DPTR, … | ||
MOVX @DPTR,A F0 |
2 | Beschreibt den externen Datenspeichers an der 16 Bit-Adresse, welche im Daten-Pointer steht, mit dem 8 Bit-Wert aus dem Akkumulator. |
Die 3 Befehle mit MOV Rr,… | ||
MOV Rr,A F8/F9/FA/FB/FC/FD/FE/FF |
1 | Kopiere den Inhalt des Akkumulators in das Register r=(0, 1, 2, 3, 4, 5, 6, 7). |
MOV Rr,adr08 A8 ??/A9 ??/AA ??/AB ??/ AC ??/AD ??/AE ??/AF ?? |
2 | Kopiere den Inhalt der 8 Bit-RAM-Adresse "adr08=??" in das Register r=(0, 1, 2, 3, 4, 5, 6, 7). |
MOV Rr,#c08 78 ??/79 ??/7A ??/7B ??/ 7C ??/7D ??/7E ??/7F ?? |
1 | Trage den 8 Bit-Wert "#c08=??" in das Register r=(0, 1, 2, 3, 4, 5, 6, 7) ein. |
Die 3+1 Befehle mit MOV @Rr,… bzw. MOVX @Rr, … | ||
MOV @Ri,A F6/F7 |
1 | Kopiere den Akkumulator-Inhalt an die RAM-Adresse "adr08", welche im Register i=(0, 1) steht. |
MOV @Ri,adr08b A6 ??/A7 ?? |
2 | Kopiere den den Inhalt der 8 Bit-RAM-Adresse "adr08b=??" in die RAM-Adresse, welche im Register i=(0, 1) steht. |
MOV @Ri,#c08 76 ??/77 ?? |
1 | Kopiere das Daten-Byte "c08" in die 8 Bit-RAM-Adresse, welche im Register i=(0, 1) steht. |
MOVX @Ri,A F2/F3 |
2 | Kopiere den Akkumulator-Inhalt an die externe RAM-Adresse "adr08", welche im Register i=(0, 1) steht. |
Die 1+1 Befehle mit POP und PUSH | ||
POP adr08 D0 ?? |
2 | Entfernt ein Byte vom Stack, weist es der direkten Adresse zu und vermindert den Stack-Pointer um 1. Diese direkte Adresse könnte ein Register, ein Counter oder etwas sonstiges direkt adressierbares sein. |
PUSH adr08 C0 ?? |
2 | Legt das Byte, worauf die direkten Adresse weist, auf den Stack und erhöht den Stack-Pointer um 1. Diese direkte Adresse könnte ein Register, ein Counter oder etwas sonstiges direkt adressierbares sein. |
Die 4 Befehle mit XCH … | ||
XCH A,adr08 C5 ?? |
1 | Tauscht den Inhalt des Akkumulators mit dem Inhalt, worauf die 8 Bit-RAM-Adresse verweist. |
XCH A,Rr C8/C9/CA/CB/CC/CD/CE/CF |
1 | Tauscht den Inhalt des Akkumulators mit dem Inhalt des Registers r=(0, 1, 2, 3, 4, 5, 6, 7). |
XCH A,@Ri C6/C7 |
1 | Tauscht den Inhalt des Akkumulators mit dem Inhalt der 8 Bit-RAM-Adresse, welche im Register i=(0, 1) steht. |
XCHD A,@Ri D6/D7 |
1 | Tauscht das untere Halbbyte des Akkumulators mit dem unteren Halbbyte, worauf die 8 Bit-RAM-Adresse verweist, welche im Register i=(0, 1) steht. |
- aus der rechts vom Komma stehenden Quelle
- in die links vom Komma stehenden Ziel
Die unterschiedlichen MOV-Befehle werden benötigt um auf die unterschiedlichen, internen (MOV) und externen (MOVX), Speicherbereiche zugreifen zu können.
Arithmetische Befehle
Mnemonik und Befehl-Code | Zyklen | Beschreibung mit Verweis auf ein Beispiel |
---|---|---|
Die 8 Befehle mit ADD … | ||
ADD A,adr08 25 ?? |
1 |
Addiert den Inhalt der angegebenen 8 Bit-RAM-Adresse
"adr08" zum Akkumulator hinzu. Formel: A=A+adr08 |
ADD A,#c08 24 ?? |
1 |
Addiert die 8 Bit-Konstante "c08"" zum Akkumulator
hinzu. Formel: A=A+#c08 |
ADD A,Rr 28/29/2A/2B/2C/2D/2E/2F |
1 |
Addiert den Inhalt des Registers
r=(0, 1, 2, 3, 4, 5, 6, 7)
zum Akkumulator hinzu. Formel: A=A+Rr |
ADD A,@Ri 26/27 |
1 |
Addiert den Inhalt der 8 Bit-RAM-Adresse,
welche im Register i=0, 1) angegebnenen ist,
zum Akkumulator hinzu. Formel: A=A+@Ri |
ADDC A,adr08 35 ?? |
1 |
Addiert den Inhalt der angegebenen 8 Bit-RAM-Adresse
"adr08" und
den Übertrage (Carry) zum Akkumulator hinzu. Formel: A=A-adr08+CF |
ADDC A,#c08 34 ?? |
1 |
Addiert die 8 Bit-Konstante "c08"" und den
Übertrage (Carry) zum Akkumulator hinzu. Formel: A=A-#c08+CF |
ADDC A,Rr 38/39/3A/3B/3C/3D/3E/3F |
1 |
Addiert den Inhalt des Registers
r=(0, 1, 2, 3, 4, 5, 6, 7)
und den Übertrage (Carry) zum Akkumulator hinzu. Formel: A=A+Rr+CF |
ADDC A,@Ri 36/37 |
1 |
Addiert den Inhalt der 8 Bit-RAM-Adresse,
welche im Register i=0, 1) angegebnenen ist,
und den Übertrage (Carry) zum Akkumulator hinzu. Formel: A=A+@Ri+CF |
Die 4 Befehle mit SUBB … | ||
SUBB A,adr08 95 ?? |
1 |
Subtrahiere den Inhalt der 8 Bit-Adressese und
den Übertrag (Carryflag, hier Borrowflag) vom Akkumulator. Formel: A=A-adr08-CF |
SUBB A,#c08 94 ?? |
1 |
Subtrahiere die 8 Bit-Konstante "c08" und
den Übertrag (Carryflag, hier Borrowflag) vom Akkumulator. Formel: A=A-#c08-CF |
SUBB A,Rr 98/99/9A/9B/9C/9D/9E/9F |
1 |
Subtrahiere den Inhalt des Registers
r=(0, 1, 2, 3, 4, 5, 6, 7) und
den Übertrag (Carryflag, hier Borrowflag) vom Akkumulator. Formel: A=A-Rr-CF |
SUBB A,@Ri 96/97 |
1 |
Subtrahiere den Inhalt der 8 Bit-RAM-Adresse, welche im Register
i=(0, 1) steht und
den Übertrag (Carryflag, hier Borrowflag) vom Akkumulator. Formel: A=A-@Ri-CF |
Die 5 Befehle mit INC … | ||
INC A 04 |
1 | Inkrementiere (Erhöhen um Eins) den Akkumulator. Formel: A=A+1 |
INC adr08 05 ?? |
1 | Inkrementiere den Inhalt der Speicherstelle,
worauf die 8 Bit-RAM-Adresse hinweist. Formel: adr08=adr08+1 |
INC DPTR C3 |
2 | Inkrementiere den Datenzeiger (DPTR). Formel: DPTR=DPTR+1 |
INC Rr 08/09/0A/0B/0C/0D/0E/0F |
1 | Inkrementiere den 8Bit-Wert im Register
r=(0, 1, 2, 3, 4, 5, 6, 7). Formel: Rr=Rr+1 |
INC @Ri 06/07 |
1 |
Inkrementiere den Inhalt der Speicherstelle,
worauf die 8 Bit-RAM-Adresse im Register i=0, 1) hinweist.
Formel: @Ri=@Ri+1 |
Die 4 Befehle mit DEC … | ||
DEC A 14 |
1 |
Dekrementiere (Verminderte um Eins) den Akkumulator. Formel: A=A-1 |
DEC adr08 15 ?? |
1 |
Dekrementiere den Inhalt der Speicherstelle,
worauf die 8 Bit-RAM-Adresse hinweist. Formel: adr08=adr08-1 |
DEC Rr 18/19/1A/1B/1C/1D/1E/1F |
1 |
Dekrementiere den 8Bit-Wert im Register
r=(0, 1, 2, 3, 4, 5, 6, 7). Formel: Rr=Rr-1 |
DEC @Ri 16/17 |
1 |
Dekrementiere den Inhalt der Speicherstelle,
worauf die 8 Bit-RAM-Adresse im Register i=(0, 1) hinweist.
Formel: @Ri=@Ri-1 |
Die 2 Befehle mit Punktrechnung | ||
DIV AB 84 |
4 |
Dividieren den Akkumulator durch den Inhalt des Registers B. Formel: A=A</B |
MUL AB A4 |
4 |
Multipliziere den Akkumulator mit dem Inhalt des Registers B. Formel: A=A*B |
Der 1 Befehle mit DA | ||
DA A D4 |
1 |
Dezimalkorrektur des Inhaltes vom Akkumulator. Formel: ??? |
Logische Befehle
Mnemonik und Befehl-Code | Zyklen | Beschreibung mit Verweis auf ein Beispiel |
---|---|---|
Die 4+2+2 Befehle mit ANL … | ||
ANL A,adr08 55 ?? |
1 |
Vernüpft den Inhalt von der Adresse "adr08""
durch logisches UND mit dem Akkumulator und legt das Ergebnis im
Akkumulator ab. Formel: A=A & adr08 |
ANL A,#c08 54 ?? |
1 |
Vernüpft die Konstante "#c08"
durch logisches UND mit dem Akkumulator und legt das Ergebnis im
Akkumulator ab. Formel: A=A & #c08 |
ANL A,Rr 58/59/5A/5B/5C/5D/5E/5F |
1 |
Vernüpft den Inhalt vom Register
r=(0, 1, 2, 3, 4, 5, 6, 7)
durch logisches UND mit dem Akkumulator und legt das Ergebnis im
Akkumulator ab. Formel: A=A & Rr |
ANL A,@Ri 56/57 |
1 |
Vernüpft den Inhalt von der Adresse die im Register
i=(0, 1) steht durch logisches UND mit dem Akkumulator und
legt das Ergebnis im Akkumulator ab. Formel: A=A & @Ri |
ANL adr08,A 52 ?? |
1 |
Vernüpft den Inhalt von der angegebnenen Adresse durch
logisches UND mit dem Akkumulator und
legt das Ergebnis an der angegebnen Adresse wieder ab. Formel: adr08=adr08 & A |
ANL adr08,#c08 53 ?? ?? |
2 |
Vernüpft den Inhalt von der angegebnenen Adresse durch
logisches UND mit der Konstante "#c08" und
legt das Ergebnis an der angegebnen Adresse wieder ab. Formel: adr08=adr08 & #c08 |
ANL C,badr 82 ?? |
2 |
Vernüpft das Bit vom Carry-Flag durch logisch UND
mit dem der angegebnenen Bit-Adresse
und legt das Ergebnis im Carry-Flag wieder ab. Formel: CF=CF & badr |
ANL C,/badr B0 ?? |
2 |
Vernüpft das Bit vom Carry-Flag durch logisch UND
mit dem negierten Bit der angegebnenen Bit-Adresse
und legt das Ergebnis im Carry-Flag wieder ab. Formel: CF=CF & !badr |
Die 3 Befehle mit CLR … | ||
CLR A E4 |
1 |
Löscht den Inhalt vom Akkumulator. Formel: A=00H |
CLR badr C2 ?? |
1 |
Lösche das direkt Bit mit der angegebnene Nummer. Formel: ??? |
CLR C C3 |
1 |
Lösche das Carry-Flag (Übertrag). Formel: CF=00H |
Die 3 Befehle mit CPL … | ||
CPL A F4 |
1 |
Komplementiere (Einer-Komplement?) den Inhalt vom Akkumulator. Formel: A=0FFH-A=!A |
CPL badr B2 ?? |
1 |
Komplementiere (Einer-Komplement?) das Bit auf der angegebenen
Adressse. Formel: Bit(badr)=!Bit(bdr) |
CPL C B3 |
1 |
Komplementiere (Einer-Komplement?) das Carry-Flag. Formel: CF=!CF |
Die 4+2 Befehle mit ORL … | ||
ORL A,adr08 45 ?? |
1 |
Vernüpft den Inhalt von der Adresse "adr08"
durch logisches ODER mit dem Akkumulator und legt das Ergebnis im
Akkumulator ab. Formel: A=A | adr08 |
ORL A,#c08 44 ?? |
1 |
Vernüpft die Konstante "#c08"
durch logisches ODER mit dem Akkumulator und legt das Ergebnis im
Akkumulator ab. Formel: A=A |#c08 |
ORL A,Rr 48/49/4A/4B/4C/4D/4E/4F |
1 |
Vernüpft den Inhalt vom Register
r=(0, 1, 2, 3, 4, 5, 6, 7)
durch logisches ODER mit dem Akkumulator und legt das Ergebnis im
Akkumulator ab. Formel: A=A | Rr |
ORL A,@Ri 46/47 |
1 |
Vernüpft den Inhalt von der Adresse die im Register
i=(0, 1) steht durch logisches ODER mit dem Akkumulator und
legt das Ergebnis im Akkumulator ab. Formel: A=A | @Ri |
ORL adr08,A 42 ?? |
1 |
Vernüpft den Inhalt von der angegebnenen Adresse durch
logisches ODER mit dem Akkumulator und
legt das Ergebnis an der angegebnen Adresse wieder ab. Formel: adr08=adr08 | A |
ORL adr08,#c08 43 ?? ?? |
2 |
Vernüpft den Inhalt von der angegebnenen Adresse durch
logisches ODER mit der Konstante "#c08" und
legt das Ergebnis an der angegebnen Adresse wieder ab. Formel: adr08=adr08 | #c08 |
ORL C,badr 72 ?? |
2 |
Vernüpft das Bit vom Carry-Flag durch logisches ODER
mit dem der angegebnenen Bit-Adresse
und legt das Ergebnis im Carry-Flag wieder ab. Formel: CF=CF | badr |
ORL C,/badr A0 ?? |
2 |
Vernüpft das Bit vom Carry-Flag durch logisches ODER
mit dem negierten Bit der angegebnenen Bit-Adresse
und legt das Ergebnis im Carry-Flag wieder ab. Formel: CF=CF | !badr |
Die 4 Befehle mit R … | ||
RL A 23 |
1 | Schiebe den Inhalt vom Akkumulator um eine Stelle nach links. Formel: A=A<-1=A*2, aber maximal 0FFH, sonst abzgl. 100H! |
RLC A 33 |
1 |
Schiebe den Inhalt vom Akkumulator über das Carry-Flag
um eine Stelle nach links.
Das obere Bit wird dabei vom Carry-Flag übernommen und
das unterste Bit des Akkumulators übernimmt dabei den alten
Bit-Wert vom Carry-Flag. Formel: A=(A<-1)+CF=(A*2)+CF, aber maximal 0FFH, sonst abzgl. 100H! |
RR A 03 |
1 |
Schiebe den Inhalt vom Akkumulator um eine Stelle nach rechts.
Das Bit 0 des Akkumulators erhält den Wert vom Bit 7.
In etwa wie eine Division durch 2. Formel: A=A>-1=A/2 |
RRC A 13 |
1 |
Schiebe den Inhalt vom Akkumulator über das Carry-Flag
um eine Stelle nach rechts.
Das untere Bit wird dabei vom Carry-Flag übernommen und
als oberstes Bit erhält den alten Wert vom Carry-Flag. Formel: A=(A>-1)+(CF*80H)! |
Die 2 Befehle mit SETB … | ||
SETB badr D2 ?? |
1 |
Setze das Bit auf Eins, welche in der Adresse angegeben worden ist. Formel: Bit(badr)=1 |
SETB C D3 |
1 |
Setze das Carry-Flag (Übertrag). Formel: CF=1 |
Der 1 Befehl bzgl. SWAP | ||
SWAP A C4 |
1 |
Vertausch das obere Halb-Byte mit dem unteren Halb-Byte. Formel: A=(A & 0FH)*10H + (A& 0F0H)/10H |
Die 4+2 Befehle mit XRL … | ||
XRL A,adr08 65 ?? |
1 |
Vernüpft den Inhalt von der Adresse "adr08""
durch logisches Exklusiv-ODER mit dem Akkumulator und legt das Ergebnis
im Akkumulator ab. Formel: A=A ^ adr08 |
XRL A,#c08 64 ?? |
1 |
Vernüpft die Konstante "#c08"
durch logisches Exklusiv-ODER mit dem Akkumulator und legt das Ergebnis
im Akkumulator ab. Formel: A=A ^ #c08 |
XRL A,Rr 68/69/6A/6B/6C/6D/6E/6F |
1 |
Vernüpft den Inhalt vom Register
r=(0, 1, 2, 3, 4, 5, 6, 7)
durch logisches Exklusiv-ODER mit dem Akkumulator und legt das Ergebnis
im Akkumulator ab. Formel: A=A ^ Rr |
XRL A,@Ri 66/67 |
1 |
Vernüpft den Inhalt von der Adresse die im Register
i=(0, 1) steht durch logisches Exklusiv-ODER mit dem Akkumulator
und
legt das Ergebnis im Akkumulator ab. Formel: A=A ^ @Ri |
XRL adr08,A 62 ?? |
1 |
Vernüpft den Inhalt von der angegebnenen Adresse durch
logisches Exklusiv-ODER mit dem Akkumulator und
legt das Ergebnis an der angegebnen Adresse wieder ab. Formel: adr08=adr08 ^ A |
XRL adr08,#c08 63 ?? ?? |
1 |
Vernüpft den Inhalt von der angegebnenen Adresse durch
logisches Exklusiv-ODER mit der Konstante "#c08" und
legt das Ergebnis an der angegebnen Adresse wieder ab. Formel: adr08=adr08 | #c08 |
Sprung-Befehle
Mnemonik und Befehl-Code | Zyklen | Beschreibung mit Verweis auf ein Beispiel |
---|---|---|
2 Befehle mit ?CALL … | ||
ACALL adr11 11/31/51/71/91/B1/D1/F1 ?? |
2 | Aufruf eines Unterprogrammes, welches in den ersten 2 kBytes abgelegt ist. Dies entspricht einer Größe von 11 Bit. Davon sind die oberen 3 Bit, dies ermöglicht 8 verschiedenen Werte, die man als Speicherseite 0 bis 7 mit einer Güße von 255 Byte interpretiert kann, im Befehl selbst enthalten. Der Assembler wählt automatisch den Operationscode aus, welcher zu der Speicherseite des Zieles passt! Spart gegenüber LCALL ein Byte Programmcode ein! |
LCALL adr16 12 ?? ?? |
2 | Aufruf eines Unterprogrammes im gesamten söglichen Speicherbereich von 64 kByte. Dies entspricht einer Größe von 16 Bit mit 65535 Möglichkeiten der Adressierung. |
4 Befehle mit CJNE … (compare jump not even) | ||
CJNE A,adr08,radr08 B5 ?? ?? |
2 | Vergleiche den Akkumulator-Inhalt mit dem Inhalt der RAM-Zelle, die in der Adresse "adr08" angegeben wurde, und springe um "radr08", wenn diese ungleich ist. |
CJNE A,#c08,radr08 B4 ?? ?? |
2 | Vergleiche den Akkumulator-Inhalt mit der Konstante "c08" und springe um "radr08", wenn diese ungleich ist. |
CJNE @Ri,#c08,radr08 B6/B7 ?? ?? |
2 | Vergleiche den Inhalt der RAM-Adresse die im Register i=(0, 1) steht mit der Konstante "c08" und springe um "radr08", wenn diese ungleich ist. |
CJNE Rr,#c08,radr08 B8/B9/BA/BC/BD/BE/BF ?? ?? |
2 | Vergleiche den Inhalt des Registers r=(0, 1, 2, 3, 4, 5, 6, 7) mit der Konstante "c08" und springe um "radr08", wenn diese ungleich ist. |
2 Befehle mit DJNZ … (decrement jump not zero) | ||
DJNZ adr08,radr08 D5 ?? ?? |
2 | Dekrementiere den Inhalt an der RAM-Adresse "adr08" und wenn dieser nicht Null geworden ist, springe um "radr08" Bytes. |
DJNZ Rr,radr08 D8/D9/DA/DB/DC/DE/DF ?? ?? Wirklich 2 zusätzliche Adress-Bytes??? |
2 | Dekrementiere den Inhalt des Registers r=(0, 1, 2, 3, 4, 5, 6, 7) und wenn dieser nicht Null geworden ist, springe um "radr08" Bytes. |
1+1+1+1 Befehle mit ?JMP … (jump) | ||
AJMP adr11 01/21/41/61/81/A1/C1/E1 ?? |
2 | Unbedingter Sprung zu einer Adresse, welche in den ersten 2 kBytes vorhanden ist. Dies entspricht einer Größe von 11 Bit. Davon sind die oberen 3 Bit, dies ermöglicht 8 verschiedenen Werte, die man als Speicherseite 0 bis 7 mit einer Güße von 255 Byte interpretiert kann, im Befehl selbst enthalten. Der Assembler wählt automatisch den Operationscode aus, welcher zu der Speicherseite des Zieles passt! Spart gegenüber LJUMP ein Byte Programmcode ein! |
JMP @A+DPTR 73 |
2 | Unbedingter Sprung zu einer Adresse, welche sich im Datenpointer DPTR befindet und um den Wert im Akkumulator durch Addition erhöht wird. Dies entspricht einer Größe von 16 Bit mit 65535 Möglichkeiten der Adressierung. |
LJMP adr16 02 ?? ?? |
2 | Unbedingter Sprung zu einer Adresse, welche sich im gesamten söglichen Speicherbereich von 64 kByte, befinden kann. Dies entspricht einer Größe von 16 Bit mit 65535 Möglichkeiten der Adressierung. |
SJMP radr08 80 ?? ?? |
2 | Unbedingter Sprung zu einer Adresse innerhalb von -128, …, +127 Bytes Speicherbereich. Spart gegenüber LJUMP ein Byte Programmcode ein und im Gegensatz von AJUMP im gesamten Speicherbereich von 64 kByte einsetzbar! |
2 Befehle mit J?C … (jump not carry) | ||
JC radr08 40 ?? |
2 |
Springe zur Adresse "radr08" relativ zur aktuellen Position,
wenn das Carry-Flag gesetzt ist. Formel: 1 == CF ? Sprung um radr08 Bytes. |
JNC radr08 50 ?? |
2 |
Springe zur Adresse "radr08" relativ zur aktuellen Position,
wenn das Carry-Flag nicht gesetzt ist. Formel: 0 == CF ? Sprung um radr08 Bytes. |
3 Befehle mit J?B … (jump not bit set) | ||
JB badr08,radr08 20 ?? ?? |
2 |
Springe zur Adresse "radr08" relativ zur aktuellen Position,
wenn das angegebenen Bit gesetzt ist. Formel: 1 == badr08 ? Sprung um radr08 Bytes. |
JBC badr08,radr08 10 ?? ?? |
2 |
Springe zur Adresse "radr08" relativ zur aktuellen Position,
wenn das angegebenen Bit gesetzt ist und lösche das Bit. Formel: 1 == badr08 ? Bit(badr08)=0 & Sprung um radr08 Bytes. |
JNB badr08,radr08 30 ?? ?? |
2 |
Springe zur Adresse "radr08" relativ zur aktuellen Position,
wenn das angegebene Bit nicht gesetzt ist. Formel: 0 == badr08 ? Sprung um radr08 Bytes. |
2 Befehle mit J?Z … (jump not zero) | ||
JZ radr08 60 ?? |
2 |
Springe zur Adresse "radr08" relativ zur aktuellen Position,
wenn der Akkumulatorinhalt Null ist. Formel: 0 == A ? Sprung um radr08 Bytes. |
JNZ radr08 70 ?? |
2 |
Springe zur Adresse "radr08" relativ zur aktuellen Position,
wenn der Akkumulatorinhalt nicht Null ist. Formel: 0 <> A ? Sprung um radr08 Bytes. |
2 Befehle mit RET … | ||
RET 22 |
2 | Rücksprung aus einem Unterprogramm. |
RETI 32 |
2 | Rückspung aus einer Interrupt-Routine. |
- 8Bit−Sprünge um eine Weite von ±128Byte.
- 11Bit−Sprünge um eine Weite von ±1.024Byte.
- 16Bit−Sprünge um eine Weite von ±32.768Byte.
Hardware
Speicherorganisation
Es gibt 2 verschiedene Arten von Speicher, den Programmspeicher und den Datenspeicher. Der Programmspeicher wird durch den Programm-Counter adressiert und der Datenspeicher durch die MOV−Befehle benutzt.
Programmspeicher
Adresse | Interner Programmspeicher |
Externer Programmspeicher |
---|---|---|
0FFFFH … 01000H |
(/EA = 0) | |
00FFFH … 00000H |
(/EA = 1) |
Datenspeicher
der Datenspeicher
Adresse | Interner Datenspeicher |
Externer Datenspeicher |
---|---|---|
0FFFFH … 0100H |
||
0FFH … 080H |
Spezielle Funktionsregister | |
07FH … 00H |
Adressierbare Bits, Registerbänke |
- internen RAM erfolgt mit MOV und
- externen RAM mit MOVX.
Interner Datenspeicher
Adresse | Registeradresse | Funktion | |||||||
---|---|---|---|---|---|---|---|---|---|
+00H | +01H | +02H | +03H | +04H | +05H | +06H | +07H | ||
0F8H | P5 | Erweiterter interner Datenspeicher, in dem auch spezielle Funktionsregister, wie Akkumulator, enthalten sind. | |||||||
0F0H | B | ||||||||
0E8H | P4 | ||||||||
0E0H | ACC | ||||||||
0D8H | ADCON | ADDATADDAT | DAPR | P6 | |||||
0D0H | |||||||||
0C8H | T2CON | CRCL | CRCH | TL2 | TH2 | ||||
0C0H | IRCON | CCEN | CCL1 | CCH1 | CCL2 | CCH2 | CCL3 | CCH3 | |
0B8H | IEN1 | IP1 | |||||||
0B0H | P3 | ||||||||
0A8H | IEN0 | ||||||||
0A0H | P2 | ||||||||
098H | SCON | SBUF | |||||||
090H | P1 | ||||||||
088H | TCON | TMOD | TL0 | TL1 | TH0 | TH1 | |||
080H | P0 | DPL | DPH | PCON |
Tabelle 10a: Belegung des internen Speichers von 000H bis 07FH vom MC 8051/8031
Adresse | Register- bzw. Bitadresse |
Funktion |
---|---|---|
07FH … 030H |
Byteadressierbarer interner Datenspeicher | |
02FH | 7FH 7EH 7DH 7CH - 7BH 7AH 79H 78H | Die 128 adressierbare Bits im interenen RAM |
02EH | 77H 76H 75H 74H - 73H 72H 71H 70H | |
02DH | 6FH 6EH 6DH 6CH - 6BH 6AH 69H 68H | |
02CH | 67H 66H 65H 64H - 63H 62H 61H 60H | |
02BH | 5FH 5EH 5DH 5CH - 5BH 5AH 59H 58H | |
02AH | 57H 56H 55H 54H - 53H 52H 51H 50H | |
029H | 4FH 4EH 4DH 4CH - 4BH 4AH 49H 48H | |
028H | 47H 46H 45H 44H - 43H 42H 41H 40H | |
027H | 3FH 3EH 3DH 3CH - 3BH 3AH 39H 38H | |
026H | 37H 36H 35H 34H - 33H 32H 31H 30H | |
025H | 2FH 2EH 2DH 2CH - 2BH 2AH 29H 28H | |
024H | 27H 26H 25H 24H - 23H 22H 21H 20H | |
023H | 1FH 1EH 1DH 1CH - 1BH 1AH 19H 18H | |
022H | 17H 16H 15H 14H - 13H 12H 11H 10H | |
021H | 0FH 0EH 0DH 0CH - 0BH 0AH 09H 08H | |
020H | 07H 06H 05H 04H - 03H 02H 01H 00H | |
01FH … 018H |
R7 … R0 |
Registerbank 3 |
017H … 010H |
R7 … R0 |
Registerbank 2 |
0FH … 08H |
R7 … R0 |
Registerbank 1 |
07H … 00H |
R7 … R0 |
Registerbank 0 |
- Speziellen Funktionsregister (SFR).
- Einen 80Byte großen Bereich welcher byteadressierbar ist.
- Einen 128Byte großen Bereich welcher bitadressierbar ist.
- Die 4 Registerbänke mit Register 0 bis 7, welche sich über R0 bis R7 ansprechen lassen. Um welche Registerbank es sich handelt, die angesprochen wird, ist über die 2 Bit im Programm-Statuswort einstellbar.
- ACC=Akkumulator
- Das Ort für den aktuellen Wert, die Stelle wo fast alles drüber läuft.
- ADAT=???
- ADCON=???
- B=Register B
- CCEN=???
- CCL1=???, CCL2=???, CCL3=???
- CCH1=???, CCH2=???, CCH3=???,
- CRCL=???
- CRCH=???
- DAPR=???
- DPL=???
- DPH=???
- IEN0=???, IEN1=???
- IP0=???, IP1=???
- IRCON=???
- P0=Port 0, P1=Port 1, P2=Port 2, P3=Port 3, P4=Port 4, P5=Port 5, P6=Port 6
- PCON=???
- PSW = Programmstatuswort
-
Es ist ein Byte,
welches 7 von den möglichen 8 Statusbit's zur Nutzung anbietet.
Diese sind
MSB … LSB PSW.7 PSW.6 PSW.5 PSW.4 PSW.3 PSW.2 PSW.1 PSW.0 CY AC F0 RS1 RS0 OV - P - AC
- Hilfesübertragungsbit z.B für BCD−Operationen.
- CY
- F0
- OV
- P
- RSx mit x=0…1
- SBUF=???
- SCON=???
- T2CON=???
- TCON=???
- TMOD=???
- TL0=???, TL1=???, TL2=???
- TH0=???, TH1=???, TH2=???
Elektor MC 8051 - Systembus
Pos. | Verwendung | ||
---|---|---|---|
a | b | c | |
1 | GND | GND | GND |
2 | GND | RD | |
3 | GND | INT0 | |
4 | GND | WR | |
5 | GND | INT1 | |
6 | GND | IOAD | |
7 | GND | Rx | |
8 | GND | Tx | |
9 | GND | ||
10 | GND | ||
11 | ALDIS | /RES | |
12 | PRG | GND | |
13 | P1.7 | P1.7 | |
14 | P1.6 | P1.6 | |
15 | P1.5 | P1.5 | |
16 | P1.4 | P1.4 | |
17 | P1.3 | P1.3 | |
18 | P1.2 | P1.2 | |
19 | P1.1 | P1.1 | |
20 | P1.0 | P1.0 | |
21 | P1DIR | P1DIR | |
22 | GND | GND | |
23 | GND | GND | |
24 | /A0 | D0 | |
25 | /A1 | D1 | |
26 | /A2 | D2 | |
27 | /A3 | D3 | |
28 | /A4 | D4 | |
29 | /A5 | D5 | |
30 | /A6 | D6 | |
31 | /A7 | D7 | |
32 | /GND | +5V |
Der Systembus ist auf einer 3*32 poligen Steckerleister nach außen geführt und kann von hier auf eine System-Bus-Platine zu anderen Steckkarten weiter geführt und genutzt werden!
Verwendete Signalnamen:- +5V = Betriebsspannung plus 5 Volt
- /Ai = /Adress-Bit i, z.dt. Low aktives Signal der Adressleitung i=0, …, 7;
- ALDIS = ???, z.dt. ???;
- Di = Daten-Bit i, Signal der Datenleitung i=0, …, 7;
- GND = Ground, z.dt. Masse;
- INT0/1 = Interrupt 0 bzw. 1, z.dt. Unterbrechungsanforderun 0 bzw. 1;
- IOAD = Input/Output-Adress, z.dt. Ein-/Ausgabe-Adressbereich wird angespochen;
- P1DIR = Port 1 Direction, z.dt. Signal-Richtung, d.h. Port 1 gibt etwas aus oder liest etwas ein;
- P1.x = Port 1.x, z.dt. der Aus-/Eingang des Pins x von Port 1;
- PRG = ???, z.dt. ???;
- RD = Read, z.dt. Lesen von aktueller Adresse;
- /RES = /Reset, z.dt. Low aktive Reset-Leitung;
- Rx = RS232 Read, z.dt. Leseleitung der seriellen Schnittstelle;
- WR = Write, z.dt. Schreiben auf aktuelle Adresse;
- Tx = RS232 Transfer, z.dt. Übertragungsleitung der seriellen Schnittstelle;