Программирование микроконтроллера на ассемблере. Симуляция игральной кости

Projekt

Würfel

8051Win- Simulation

von Ilya Gufan, 4G5

Heilbronn, Juni 2006

Inhaltsverzeichnis

·        Lastenheft                                                                                        3

·        Einführung                                                                                       4

·        Aufgaben                                                                                          5

o   Aufgabe 1. 8051Win-Simulation mit LED-Reihe                             6

o   Aufgabe 2. Programmierung der BB-Mikrocontrollerplatine         12

o   Aufgabe 3. 8051Win-Simulation des Würfelmodells            17

o   Aufgabe 4. 8051Win-Simulation der 7-Segment-Anzeige     23

o   Aufgabe 5. Programmierung der 7-Segment-Anzeige            27

o   Aufgabe 6. Langsam auslaufender oder nachlaufender Zähler        29

·        Beschreibung der benutzten Befehle                                                        32

·        Quellenangabe                                                                                33

Anlage: CD

Lastenheft

1. 8051Win-Simulation mit LED-Reihe

a) Dualanzeige des Zählers /DJNZ-Befehl und CJNE-Befehl

b) Start-Stopp Schalter / Bitverarbeitung und bedingte Sprünge

c) Ausgabe auf die LPT-Schnittstelle / Parallele Schnittstelle

d) Ausgabe als Leuchtbalken / Decoder / Unterschied von Wert und Adresse

e) Vollständige Dokumentation mit Programmablaufplänen, Code,

Erklärungen, Snapshots

2. Programmierung der BB-Mikrocontrollerpiatine

a) EEPROM / Flash-EPROM / Harvard-Struktur / Adressbereiche

b) Zählerausgabe auf die LED-Reihe

c) Zeitprogramm / Unterprogramme / Zeitberechnung / Stackpointer

d) Befehlsabarbeitung

e) Vollständige Dokumentation mit Programmablaufplänen, Code,

Erklärungen, Snapshots

3 . 8051Win-Simulation

a) Würfelmodell mit integriertem Decoder

b) Würfelmodell ohne Decoder /indirekte Adressierung @R0, @R1 im 8bit-

Adressraum Code in Adr. 31h ... 36h abspeichern

c) Vollständige Dokumentation mit Programmablaufplänen, Code,

Erklärungen, Snapshots

4. 8051Win-Simulation

a) Siebensegmentmodell / Indirekte Adressierung @DPTR im 16 bit-

Adressraum / Define Byte (DB)

b) Übersicht aller Adressierungsarten.

c) Vollständige Dokumentation mit Programmablaufplänen, Code,

Erklärungen, Snapshots

5. Programmierung der BB-Mikrocontrollerplatine

a) Ausgabe auf 7-Segment-Anzeige /arbeiten mit CJNE-Befehl / DPTR / DB

b) Vollständige Dokumentation mit Programmablaufplänen, Code, Erklärungen, Snapshots

6. Zusatzaufgabe (freiwillig)

a) Langsam auslaufenden / nachlaufenden Zähler entwickeln

b) Vollständige Dokumentation mit Programmablaufplänen, Code,

Erklärungen, Snapshots

7. Vollständige Projektdokumentation incl. Deckblatt, Inhaltsverzeichnis, Lastenheft, Quellangaben und a51- wie hex-Code auf Diskette / CD

Bild 1. Würfelset für das Spiel »Dungeons & Dragons«

Einführung

Dieses Projekt wurde im Rahmen des CT-Unterrichts gemacht. Der Projektleiter ist Herr A. Hein. Das Ziel des Projektes war, die Assembler-Programmierung des µC zu meistern. Das zu programmierende Objekt war der Würfel. Die Ausführung der Programme sollte mit 8051win simuliert werden. Während des Unterrichts hatte der Schüler auch die Möglichkeit, mit dem BB-µC-Platine das Programm direkt auf dem µC ausführen zu lassen.

Bild 2. Würfel üblicher Form

Bild 3. Ein falscher Würfel

Ein Spielwürfel ist ein als Zufallsgenerator verwendeter Gegenstand, der auf mehrere, voneinander unterscheidbare Arten stabil auf der Ebene zu liegen kommen kann. Die meisten Würfel sind heute aus Holz oder Kunststoff und haben einen Durchmesser von etwa eineinhalb Zentimetern. Spielwürfel werden vor allem in den nach ihnen benannten Würfelspielen und in Glücksspielen, gelegentlich auch in Brettspielen und in Rollenspielen (wie z. B. »Dungeons & Dragons«) verwendet.

Die übliche Form ist die eines geometrischen Würfels, worauf auch der Begriff Spielwürfel zurückgeht. Um seine Rolleigenschaft zu verbessern, sind die Ecken heute häufig abgerundet. Die Flächen sind meistens mit ein bis sechs Punkten versehen, die auch als Augen bezeichnet werden, wobei die Augensumme sich gegenüberliegendener Seiten in der Regel sieben ergibt. Die Orientierung der gegenüberliegenden Paare (1,6), (2,5), (3,4) ist im westlichen Kulturkreis so festgelegt, dass die Ziffern 1, 2 und 3 im Gegenuhrzeigersinn gesehen werden, während sie im Fernen Osten im Uhrzeigersinn ausgerichtet sind.

In dem Projekt wird ein Würfel üblicher Form programmiert.

Aufgaben

·      Dualanzeige des Zählers

·      LED-Reihe

·      Würfelmodell

·      Siebensegmentmodell

Aufgabe 1. 8051Win-Simulation mit LED-Reihe

LED-Dualanzeige des Zählers.

Bild 4. LED-Dualanzeige in 8051Win-Simulation

Erklärung:

Man baut einen einfachen Zähler von 1 bis 6 bzw. von 6 bis 1 auf. Der Schalter wird durch P1 mit der Adresse 90h, die Ausgabe auf P2 mit der Adresse 0A0h festgelegt. Danach wird der Wert 6 bzw. 1 ins Register 1 geladen (Programmpunkt „laden“). Dann wird der Schalter überprüft, ob er auf 1 gesetzt ist. Wenn ja, überprüft man wieder.  Wird er auf Null gesetzt, so lässt man das Programm weiter laufen (Programmpunkt „stopp“).

Danach gibt man den Registerinhalt von R1 auf P2.

Lösung mit DJNZ.

Mit DJNZ wird der Registerinhalt um eins verkleinert, deshalb zählt man von 6 bis 1. Sobald das Ergebnis Null ist, wird der Code weiter abgearbeitet. Mit dem Befehl SJMP springt es zum Programmpunkt „laden“. Ist das Ergebnis keine Null, wird es zum Programmpunkt „stopp“ gesprungen.

Lösung mit CJNE.

Mit INC wird der Registerinhalt um eins erhöht. Man zählt von 1 bis 6. Ist der Inhalt von R1 dem Wert 07h nicht gleich, wird es zum Programmpunkt „stopp“ gesprungen. Im Falle der Gleichheit wird zu dem Programmpunkt „laden“ gesprungen.

Man braucht keine Codierungstabelle, da man keinen Decoder hat.

Bild 6. Programmablaufplan für die Lösung mit INC

Programmablaufpläne

Bild 5. Programmablaufplan für die Lösung mit DJNZ

 

Assemblercode

א) von 6 bis 1 (mit DJNZ)

Code at 0000h

P1 equ 90h               ; Start-Stopp-Schalter

P2 equ 0A0h              ; Ausgabe erfolgt an der Adresse 0A0h

laden: mov R1, #06h      ; Wert 6 wird in R1 geladen

stopp:  JB P1.0, stopp   ; Bei geschaltetem Schalter (d. h.                          ; bei gesetztem Bit) wird es zu Stopp                          ; gesprungen

count: mov P2, R1        ; Hier erfolgt die Ausgabe an die                          ; Adresse 0A0h (durch P2)

          djnz R1, stopp ; Register wird um 1 verkleinert und                          ; verzweigt, wenn Ergebnis ungleich                          ; Null

          sjmp laden

end                      ; Ende des Programms

ב) von 1 bis 6 (mit INC und CJNE)

Code at 0000h

P1 equ 90h               ; Register Start-Stopp-Schalter

P2 equ 0A0h              ; Ausgabe erfolgt an die Adresse                          ; 0A0h

   

laden: mov R1, #01h      ; Wert 1 wird ins Register R1 geladen

stopp: JB P1.0, stopp    ; Bei geschaltetem Schalter (d. h.                          ; bei gesetztem Bit) wird es zu Stopp                          ; gesprungen

count: mov P2, R1        ; Hier erfolgt die Ausgabe an die                          ; Adresse 0A0h d. h. an P2

    inc R1               ; Registerinhalt wird um eins erhöht

    cjne R1, #07h, stopp ; Ist Registerinhalt ungleich #07h,                          ; erfolgt die Verzweigt zu Stopp

    sjmp laden           ; Es wird zu Laden gesprungen

end                      ; Ende des Programms

Ausgabe auf die LPT-Schnittstelle

Ausgabe equ und mov

Bild 7. Auswahl der Schnittstelle LPT1

P2 equ 0A0h

mov P2, #data

Zuerst wird die Adresse 0A0h dem P2 zugewiesen, danach werden die Daten (#data) ausgegeben. Mit dem Befehl mov können einer bestimmten Adresse verschiedene Sachen zugeordnet werden z.B. Wert, Daten oder eine andere Adresse.

Auf diese Weise lässt sich auch die Ausgabe auf die LPT Schnittstelle und Parallele Schnittstelle realisieren.

In dem Programm 8051Win können wir dem Port eine Schnittstelle zuweisen, bei dem Programm ist es LPT1.

Bild 8. Screenshot von 8051Win

Ausgabe als Leuchtbalken.

Aufgabe: Nun sollen die Zahlen nicht als ein binärer Wert von 0001 bis 0101 einfach ausgegeben werden. Es soll ein Decoder Programmiert werden, welcher die Aufgabe hat: Die Anzahl der LED, die leuchten, ist gleich der Zahl.

Erklärung:

Codierungstabelle für diese Aufgabe steht unten.

Die Binärzahl entspricht der daneben stehenden Hexzahl. Eine Lösungsvariante besteht darin, dass man diese Hexzahlen einfach der Reihe nach ausgibt, dabei muss aber jedes Mal geprüft werden, ob der Schalter auf „1“ gelegt wurde. Wenn ja, muss der Ablauf angehalten werden.

Codierungstabelle:

Ausgabewert

Hexzahl

Binärzahl

Eins

01h

0000 0001b

Zwei

03h

0000 0011b

Drei

07h

0000 0111b

Vier

0Fh

0000 1111b

Fünf

1Fh

0001 1111b

Sechs

3Fh

0011 1111b

Assemblercode (1d)

Code at 0000h

P1 equ 90h            ;Schalter

P2 equ 0A0h           ;LED's

count:                ;Programmpunkt für die Schleife

mov P2, #01h          ;Wertausgabe, 1x LED leuchtet

stopp1: JB P1.0, stopp1 ;Bei gesetztem Bit STOP

mov P2, #03h          ;Wertausgabe, 2x LED's leuchten

stopp2: JB P1.0, stopp2   ;Bei gesetztem Bit STOP

mov P2, #07h         ;Wertausgabe, 3x LED's leuchten

stopp3: JB P1.0, stopp3   ;Bei gesetztem Bit STOP

mov P2, #0Fh         ;Wertausgabe, 4x LED's leuchten

stopp4: JB P1.0, stopp4   ;Bei gesetztem Bit STOP

mov P2, #1Fh          ;Wertausgabe, 5x LED's leuchten

stopp5: JB P1.0, stopp5   ;Bei gesetztem Bit STOP

mov P2, #3Fh          ;Wertausgabe, 6x LED's leuchten

stopp6: JB P1.0, stopp6   ;Bei gesetztem Bit STOP

sjmp count             ;Es wird zu count gesprungen

end

Programmablaufplan zu 1d

Bild 9. Programmablaufplan zu 1d

Aufgabe 2. Programmierung der BB-µC-Platine

Speicherarten und Harvard-Struktur

(א Speicherarten

Ein µC-System benötigt immer einen Programm- und Datenspeicher. Der Inhalt des Programmspeichers wird vom Mikroprozessor nur gelesen, während der Datenspeicher sowohl gelesen als auch beschrieben wird. Für den Programmspeicher werden deswegen ROMs (read only memory, lese-nur-Speicher) eingesetzt. Der Programmspeicher muss ein nichtflüchtiger Speicher sein d.h. ein Speicher der seinen Inhalt auch dann nicht verliert, wenn die Versorgungsspannung abgeschaltet wird.

EEPROM (Electrically Erasable Programmable Read Only Memory)

Ist elektrisch programmierbar und auch elektrisch löschbar. Das Programmieren und Löschen kann nicht beliebig schnell erfolgen, deswegen müssen dabei bestimmte Mindestzeiten eingehalten werden.

Flash-Speicher

Hat im Vergleich zu EEPROM wesentlich kürzere Programmier- und Löschzeiten. Die Speicherzellen können nicht mehr, wie im EEPROM einzeln sondern nur Blockweise gelöscht werden.

Diese Speicherart wird im Mikrocontroller als eine Art des ROM Speichers (nur Lese-Speicher) benutzt. In ihm wird der Programmcode abgelegt. Bei der Abschaltung des Stromes gehen die Daten nicht verloren.

RAM-Speicher (Random Access Memory, Schreib-Lese-Speicher)

Für den Datenspeicher benötigt man einen Speicher, den man sehr schnell lesen und beschreiben kann. Für diese Aufgabe verwendet man Halbleiterspeicher, die auf der Basis von Flip-Flops aufgebaut sind.

RAM-Speicher verliert seine Daten bei Stormabschaltung, d. h. sie ist flüchtig. 

(ב Harvard-Struktur

Bild 10. Harvard-Struktur

Alle Microcontroller der Familie 8051 verfügen über getrennte Adressierbereiche für den Programmspeicher und den Datenspeicher, welche am gleichen Adressbus liegen.

Der Zugriff auf den exteren Programmspeicher wird über das Signal  (Programm Store Enable) gesteuert. Für den Zugriff auf den Datenspeicher stehen die Signale  (read) und  (write) zur Verfügung. Die Struktur eines solchen Speichersystems wird Harvard-Struktur genannt.

Die Harvard Struktur wird während des normalen Betriebs des Mikrocontrollers verwendet.

Zeitprogramm, Zeitberechnung

Bild 11. Das Auge merkt keine Pausen.

Erklärung.

Das menschliche Auge ist in der Lage, die Ereignisse wahrzunehmen, die länger, als ca.

Schleife:

zeit: DJNZ R1, zeit

Einmaliges durchführen dieser Schleife (bei R1 = #01h) dauert bei unserem µC 2 µs.

Man programmiere eine Schleife, die ca. 0,2 s läuft. 1 s entspricht 100 000 Schleifen:

Folglich brauchen wir sie 100 000 durchlaufen zu lassen, um 0,2 s Zeitpause zu bekommen.

Unterprogramm

Unterprogramm

uptime:

mov R3, #10            ; lädt 10 in R3 ein

loop3: mov R2, #100    ; Unterschleife; lädt 100 in R2 ein

loop2: mov R1, #100    ; Unterschleife; lädt 100 in R2 ein

loop1: djnz R1, loop1  ; bedingter Sprung zurück

       djnz R2, loop2  ; bedingter Sprung zurück

       djnz R3, loop3  ; bedingter Sprung zurück

RET                         ; Das Programm wird an der Stelle                             ; fortgesetzt, an der das Unter-                             ; programm aufgerufen wurde, also                             ; nach der lcall uptime

Das Unterprogramm wird aufgerufen, durchgeführt und mit RET kehrt man an den Punkt zurück, von welchem es aufgerufen wurde.

Stackpointer und Stackspeicher.

Die Adresse, an die es zurückspringen muss, wird im Stack-Speicher gespeichert. Der Stackpointer zeigt auf den Platz im Stack-Speicher, in dem die Adresse gespeichert ist.

Ein Stack dient somit zur Zwischenspeicherung der Rücksprungsadressen bei Unterprogrammen.

Zählerausgabe auf die LED-Reihe.

Erklärung

Die Lösung ist wie bei № 1d, jedoch mit einer Erweiterung:

Zwischen den Ausgaben von Zahlen wird jedes Mal ein Unterprogramm „up1sek“ aufgerufen. Das Unterprogramm verbraucht die Zeit von etwa 1Sekunde. Danach wird das Programm weiter an dem Punkt fortgesetzt von dem das Unterprogramm aufgerufen wurde.

Unterprogramm:

In die Register R1, R2, R3 wird jeweils eine Dezimalzahl unmittelbar geladen. In einer Schleife werden diese Zahlen bis Null runtergezählt. Danach wird es wieder mit RET an den Punkt des Aufrufs zurückgesprungen.

Assemblercode

Code at 0000h

P1 equ 90h             ; Schalter

P2 equ 0A0h            ; LEDs

count:                 ; Anfang der Hauptschleife

mov P2, #01h           ; 1 LED ist an.

lcall uptime           ; Aufruf des Unterprogramms für Pause

stopp1: JB P1.0, stopp1; Beim gesetzten bit stoppen.

mov P2, #03h           ; 2 LEDs ist an.

lcall uptime           ; Aufruf des Unterprogramms für Pause

stopp2: JB P1.0, stopp2; Beim gesetzten bit stoppen.

mov P2, 07h            ; 3 LEDs ist an.

lcall uptime           ; Aufruf des Unterprogramms für Pause

stopp3: JB P1.0, stopp3; Beim gesetzten bit stoppen.

mov P2, 0Fh            ; 4 LEDs ist an.

;

lcall uptime           ; Aufruf des Unterprogramms für Pause

stopp4: JB P1.0, stopp4; Beim gesetzten bit stoppen.

mov P2, 1Fh            ; 5 LEDs ist an.

; lcall uptime           ; Aufruf des Unterprogramms für Pause

stopp5: JB P1.0, stopp5; Beim gesetzten bit stoppen.

mov P2, 3Fh            ; 6 LEDs ist an.

lcall uptime           ; Aufruf des Unterprogramms für Pause

stopp6: JB P1.0, stopp6; Beim gesetzten bit stoppen.

;

ORG 0F0h

uptime:

mov R3, #10            ; lädt 10 in R3 ein

loop3: mov R2, #100    ; Unterschleife; lädt 100 in R2 ein

loop2: mov R1, #100    ; Unterschleife; lädt 100 in R2 ein

loop1: djnz R1, loop1  ; bedingter Sprung zurück

       djnz R2, loop2  ; bedingter Sprung zurück

       djnz R3, loop3  ; bedingter Sprung zurück

RET                         ; Das Programm wird an der Stelle                             ; fortgesetzt, an der das Unter-                             ; programm aufgerufen wurde, also                             ; nach der lcall uptime

END

Programmablaufpläne (siehe auch 1d)

Bild 12. Programmablaufplan der Aufgabe 2

Bild 13. Unterprogrammablaufplan für die Zeitpause „uptime“

Aufgabe 3. 8051Win-Simulation von Würfelmodell

Hexzahlenberechnung für die Ausgabe auf dem Würfel-2 in 8051Win

W-Anzeige

4

2

1

8

4

2

1

Dual

Hexergebnis

Belegung

-

D6

D5

D4

D3

D2

D1

D0

    linke hex – rechte hex

-

Augenzahl 1

0

0

0

0

1

0

0

0

8

08h

Augenzahl 2

0

0

1

0

0

0

1

0

2 – 2

22h

Augenzahl 3

0

0

1

0

1

0

1

0

    2 – 8+2

2Ah

Augenzahl 4

0

1

0

1

0

1

0

1

 4+1 – 4+1

55h

Augenzahl 5

0

1

0

1

1

1

0

1

     4+1 – 8+4+1

5Dh

Augenzahl 6

0

1

1

1

0

1

1

1

4+2+1 – 4+2+1

77H

a) Würfelmodell mit integriertem Decoder

Bild 15. Screenshot von 8051Win

Erklärung

Da der Würfel einen integrierten Decoder besitzt, kann der Zähler aus der Aufgabe 1 benutzt werden. Dieser Zähler gibt die Zahlen an P2 aus. Der Decoder wandelt die Zahlen in entsprechend andere Zahlen, damit die Würfelaugen richtig leuchten.

Assemblercode

Code at 0000h

P1 equ 90h               ; Start/Stopp Schalter

P2 equ 0A0h              ; Ausgabe erfolgt an der Adresse 0A0h

   

laden: mov R1, #01h      ; Wert #01h wird ins Register R1 geladen

stopp:  JB P1.0, stopp   ; Bei geschaltetem Schalter (gesetztem                          ; Bit) wird es zu Stopp gesprungen.

mov P2, R1        ; Hier erfolgt die Ausgabe an Adresse 0A0h,                          ; d. h. an P2.

    inc R1               ; Registerinhalt wird um eins erhöht.

    cjne R1, #07h, stopp ; Wenn Registerinhalt ungleich #07h ist,                          ; dann verzweigt das Programm zu Stopp

    sjmp laden           ; Es wird zu Laden gesprungen

End

Programmablaufplan

Bild 16. Programmablaufplan vom Würfelmodell mit integriertem Decoder

Bild 17. Screenshot von 8051Win

b) Würfelmodell ohne Decoder mit indirekter Adressierung

Erklärung

Bild 18. Zwei Würfelaugen leuchten.

Bei dieser Aufgabe besitzt der Würfel keinen integrierten Decoder, die Würfelaugen müssen trotzdem richtig leuchten. Das heißt, dass bei einer Zwei auch die richtigen zwei Würfelaugen leuchten müssen (s. Bild 18). Die folgende Codierungstabelle enthält die Hexzahlen, die für jeden Ausgabewert (1 bis 6) die richtigen Würfelaugen zum Leuchten bringen.

Ausgabewert

Hexzahl

Eins

08h

Zwei

41h

Drei

49h

Vier

55h

Fünf

5D4

Sechs

77h

Diese Hexzahlen werden gemäß der Aufgabestellung im Adressbereich 31h…36h abgespeichert. Der Zähler geht dann diesen Adressbereich immer wieder durch. Durch die indirekte Adressierung werden diese Hexzahlen nacheinander ausgegeben.

Assemblercode

Code at 0000h

P1 equ 90h   ; Schalter

P2 equ 0A0h  ; Ausgabe

; Decoder:

; es werden bestimmte Werte in dem

; Adressbereich 31h bis 36h

; abgespeichert

;------------------------

mov 31h, #08h

mov 32h, #41h

mov 33h, #49h

mov 34h, #55h

mov 35h, #5Dh

mov 36h, #77h

;------------------------

laden: mov R1, #31h   ; im R1 wird der Wert

                      ; 31h abgespeichert

       mov A, @R1     ; in A steht jetzt der

                      ; Wert 08h (indirekte

                      ; Andressierung)

       mov P2, A      ; Akkuinhalt wird

                      ; ausgegeben

stopp: JB P1.0, stopp ; Stopp/Start-Schalter

count:

inc R1                ; erhohe R1

mov A, @R1            ; in A wird der Wert der

                      ; Adresse, welche in R1

                      ; steht, abgespeichert.

mov P2, A             ; Ausgabe des Akkuinhalts

cjne A, #77h, stopp   ; Verzweigen zum Stopp bei

                      ; Ungleichheit.

sjmp laden            ; Sprung zum Laden

END

Programmablaufplan

Bild 19. Programmablaufplan für die Aufgabe 3b

Aufgabe 4. 8051Win-Simulation der 7-Segment-Anzeige

Bild 20. Screenshot von 8051Win

Erklärung

In dieser Aufgabe werden die Zahlen von 1 bis 6 durch eine 7-Segment-Anzeige dargestellt.

Zur Lösung der Aufgabe benützen wir eine indirekte Adressierung @DPTR im 16 bit- Adressraum und Define Byte (DB).

Die Zahlen 1 bis 6 haben folgende Entsprechungen:

Ausgabewert

Hexzahl

Eins

12h

Zwei

0BCh

Drei

0B6h

Vier

0D2h

Fünf

0E6h

Sechs

0EEh

Am Ende der Datenzeile setze man 0FFh, um das Ende der Zeile zu markieren (end of line).

Assemblercode

Code at 0000h

P2 equ 0A0h

P3 equ 0B0h

clr P3.6                ; Eine 7-Segment-Anzeige loeschen/abschalten

init: mov DPTR, #Daten  ; Daten laden

start: clr A            ; Akku loeschen

movC A, @A+DPTR         ; Indirekte 16-Bit-Adressierung.

                        ; Es wird auf diese Weise wegen der

                        ; Besonderheiten des Prozessors gemacht.

                        ;

CJNE A, #0FFh, weiter   ; Pruefe, ob "end of line" (Ende der Zeile).

sjmp init               ; Wenn ja, von Anfang an.

weiter: mov P2, A       ; Ausgabe des Akkuinhaltes

INC DPTR                ; Naechstes Datum nehmen.

sjmp start              ; Zurueck zu Start

ORG 0C0h  

Daten: DB 12h, 0BCh, 0B6h, 0D2h, 0E6h, 0EEh, 0FFh

                        ; Liste der Zustaende der 7-Segment-Anzeige,

                        ;                                    1 bis 6

END

Programmablaufplan

Bild 21. Programmablaufplan für die Aufgabe 4

Adressierungsarten

1. Unmittelbare Adressierung.

Einer Variable (einem Speicherplatz, dem Akku oder einem Register) wird unmittelbar ein Wert zugeordnet.

#01h->R1

oder

mov R1, #01h

2. Direkte Adressierung.

Einer Variable (einem Speicherplatz, dem Akku oder einem Register) wird direkt der Inhalt Wert einer anderen Variable (eines Speicherplatzes, des Akkus oder eines Registers) zugeordnet.

<A>->R1

oder

mov R1, A

3. Indirekte Adressierung.

Einer Variable (einem Speicherplatz, dem Akku oder einem Register) wird direkt der Inhalt der Speicherzelle zugeordnet, deren Adresse dem Inhalt einer anderen Variable (eines Speicherplatzes, des Akkus oder eines Registers) entspricht.

<<A>>->R1

oder

mov A, 0ACh

mov R1, @A

Nach dem Ausführen steht der Inhalt der Speicherzelle mit der Adresse 0ACh in R1.

Aufgabe 5. Programmierung der 8051Win-Simulation der 7-Segment-Anzeige

Erklärung

In dieser Aufgabe werden die Zahlen von 1 bis 6 durch eine 7-Segment-Anzeige dargestellt. Zur Lösung der Aufgabe benützen wir CJNE-Befehl, DPTR und Define Byte (DB).  Die Aufgabe 5 ist im Prinzip die Aufgabe 4. Jedoch benötigen wir hier eine Zeitpause, damit wir den Ergebnis prüfen können.

Die Programmierung wurde erfolgreich während des Unterrichts durchgeführt. Die Simulation mit dem Programm 8051Win ist wegen der Zeitpause nicht sinnvoll.

Assemblercode

Code at 0000h

P2 equ 0A0h

P3 equ 0B0h

clr P3.6                ; Eine 7-Segment-Anzeige loeschen/abschalten

init: mov DPTR, #Daten  ; Daten laden

start: clr A            ; Akku loeschen

movC A, @A+DPTR         ; Indirekte 16-Bit-Adressierung.

                        ; Es wird auf diese Weise wegen der

                        ; Besonderheiten des Prozessors gemacht.

                        ;

CJNE A, #0FFh, weiter   ; Pruefe, ob "end of line" (Ende der Zeile).

sjmp init               ; Wenn ja, von Anfang an.

weiter: mov P2, A       ; Ausgabe des Akkuinhaltes

lcall uptime            ; Zeitpause

INC DPTR                ; Naechstes Datum nehmen.

sjmp start              ; Zurueck zu Start

ORG 0C0h  

Daten: DB 12h, 0BCh, 0B6h, 0D2h, 0E6h, 0EEh, 0FFh

                     ; Liste der Zustaende der 7-Segment-Anzeige.

uptime:

mov R3, #10            ; lädt 10 in R3 ein

loop3: mov R2, #100    ; Unterschleife; lädt 100 in R2 ein

loop2: mov R1, #100    ; Unterschleife; lädt 100 in R2 ein

loop1: djnz R1, loop1  ; bedingter Sprung zurück

       djnz R2, loop2  ; bedingter Sprung zurück

       djnz R3, loop3  ; bedingter Sprung zurück

RET                         ; Das Programm wird an der Stelle                             ; fortgesetzt, an der das Unter-                             ; programm aufgerufen wurde, also                             ; nach der lcall uptime

END

Programmablaufplan.

 

Bild 22. Programmablaufplan für die Aufgabe 5

Aufgabe 6. Langsam auslaufender/nachlaufender Zähler

Erklärung.

Bild 23. BB-Mikrocontrollerplatine

Die Aufgabe 6 ist eine Erweiterung der Aufgaben 4 und 5. Jetzt brauchen wir, dass der Zähler mit einer Beschleunigung oder verzögerung zählt.

Die Programmierung wurde erfolgreich während des Unterrichts durchgeführt. Die Simulation mit dem Programm 8051Win ist wegen der Zeitpause nicht sinnvoll.

Assemblercode

Code at 0000h

P1 equ 90h

P2 equ 0A0h

P3 equ 0B0h

clr P3.6                ; eine 7-Segment-Anzeige abschalten

mov 0F9h, #1            ; eins in die Speicherzelle 0F9h laden

init: mov DPTR, #Daten  ; s. Bemerkungen zu Nr. 4 und 5

start: clr A

       movC A, @A+DPTR

       CJNE A, #0FFh, weiter

       sjmp init

weiter: mov P2, A

stopp: JB P1.0, beschleunigen ; wenn P1.0-Schalter auf 1 steht,

                             ;beschleunigen

langsamer:                  ;

       mov R4, 0F9h          ; der Inhalt der Speicherzelle 0F9h ins

                             ;R4 laden

       cjne R4, #7, verzoegern ; vergleichen mit #7.

                             ;Bei Ungleichheit zum Verzoegern (also

                             ;einfach weiter) gehen

       sjmp stopp             ; Bei Gleichheit zum Stopp gehen

verzoegern:

       inc R4                ; durch Erhoehung von R4 macht man die

                             ; Pause laenger

       mov 0F9h, R4          ; Inhalt von R4 ins R3 ueber

       mov R3, 0F9h          ; eine Speicherzelle laden

       sjmp vor              ; Zur Pause springen

beschleunigen:

       mov R3, #1

       mov R4, 0F9h

       cjne R4, #1, go       ; wenn noch keine 1, beschleunigen 

                             ; durch go

       sjmp vor

go:

       dec R4                ; durch Verkleinerung von R4 macht man

;                            ; die Pause kuerzer

       mov 0F9h, R4          ; Inhalt von R4 ins R3 ueber

       mov R3, 0F9h          ; eine Speicherzelle laden

vor:

       LCALL uptime         ; Pause ausführen

       INC DPTR             ; naechstes Datum nehmen.

       sjmp start

Daten: DB 12h, 0BCh, 0B6h, 0D2h, 0E6h, 0EEh, 0FFh;

ORG 0C0h

uptime:

loop3: mov R2, #200

loop2: mov R1, #250

loopl: djnz R1, loopl

       djnz R2, loop2

       djnz R3, loop3

RET

END

Programmablaufplan

Bild 24. Programmablaufplan für die Aufgabe 6

Beschreibung der benutzten Befehle

Code at Adresse

Legt fest, ab welcher Adresse der Programmcode gespeichert wird. Bei uns ist es immer ab Anfang.

end

Ein Assembler-Programm wird mit dem Befehl End beendet.

DJNZ (Decrement Jump if Not Zero; dekrementiere, springe, wenn nicht Null)

DJNZ Adresse, rel

oder   

DJNZ Rn, rel

Der Befehl vermindert Adresseinhalt (Adresse) bzw. Registerinhalt (Rn) um eins und verzweigt zu rel, wenn das Ergebnis ungleich Null ist.

CJNE – Befehl (Compare Jump if Not Equal)

CJNE Adresse, #data, rel                 oder                CJNE Adresse, Adresse, rel

Vergleicht Adresse mit #data / Adresse und verzweigt nach rel wenn es ungleich ist.

JB (Jump Bit)

JB bit, rel

Springt zu rel beim gesetzten Bit (bit)

Ausgabe EQU und MOV

P2 equ 0A0h

mov P2, #data

Zuerst wird die Adresse 0A0h dem P2 zugewiesen, danach werden die Daten (#data) ausgegeben. Mit dem Befehl mov können einer bestimmten Adresse verschiedene Sachen zugeordnet werden z.B. Wert, Daten oder eine andere Adresse.

Auf diese Weise lässt sich auch die Ausgabe auf die LPT Schnittstelle und Parallele Schnittstelle realisieren.

SJMP (Short Jump)

SJMP Programmpunkt

Relativer Programmsprung im Bereich -128 bis 127 zur nachfolgenden Befehlsadresse.

LCALL

Mit diesem Befehl wird ein Unterprogramm aufgerufen (LCALL Unterprogrammname)

RET

Der Befehl lässt das Programm an die Stelle zurückspringen, an der er aufgerufen wurde und das Programm läuft dort weiter.

INC und DEC

Mit den Befehlen wird der Wert um 1 erhöht bzw. verkleinert.

ORG

Der Befehl legt fest die Stelle, an der der nachfolgende Quellcode abgelegt wird. Er ist mit dem Befehl „Code at Adresse“ vergleichbar (ORG Adresse). Der Wert liegt zwischen 00h und FFh.

Quellenangabe

1.     Im Unterricht angeeignetes Wissen

2.    CD von Herrn A. Hein mit Programmen und Erklärungen

3.    Wikipedia (www.wikipedia.org)

4.    http://www.humerboard.at/

5.    Modul-Hardware ( http://www.humerboard.at/doku/sb8/hardware_sb8.pdf )

6.    Uthishdran Sreeranganathan stellte mir das Foto der BB-Mikrocontrollerplatine zur Verfügung

Anlage: CD