Pfad: Home =>
AVR-Übersicht =>
Tutorium => Teil 1
; Test 1: Board kennenlernen, Ausgabe an die Leuchtdioden.
; Was es hier zu lernen gibt:
; - Einen Ausgabe-Port ansteuern (Port
B mit den LEDs)
; - Aus welchen Teilen ein Programm besteht.
; Von mir verwendete Konventionen:
; - Gross geschriebene Wörter kennzeichnen vordefinierte Befehlsworte
; oder mit dem Prozessortyp vordefinierte Ports.
; - Klein geschriebene Worte sind von mir definiert und willkürlich
; gewählt.
; Prozessor definieren
;
.NOLIST
.INCLUDE "8515def.inc"
.LIST
; Die Befehle NOLIST und LIST schalten das Auflisten der INCLUDE-Datei
; in der Datei TEST1.LST aus.
; Register definieren
;
; Dieses Register wird für die Zwischenspeicherung der Zahlen
; verwendet. Mit dem Befehl .DEF kriegt
eins der 32 8-Bit-Register
; einen Namen (hier: mp), den man sich einfacher merken kann als
; R16. Ausserdem kann man einfacher Register verlegen, wenn man sie
; über einen Namen anspricht.
.DEF mp = R16
; Restart
;
; Bis jetzt war alles Vorgeplänkel. Hier beginnt nun das Programm.
; mit dem Reset- und Interrupt-Sprung-Teil.
Dieser Teil
; produziert die ersten Programm-Bytes
an der Adresse 0000 und
; folgende.
; Vorerst besteht dieser Teil nur aus einem Sprungbefehl in
das
; Hauptprogramm. Dieser Befehl wird bei jedem Neustart des Pro-
; zessors ausgeführt. Ein Neustart wird bei Power-On, bei einem
; Hardware-Reset am Reset-Pin
oder durch den Watchdog-Timer
; ausgelöst. Der Watchdog ist in diesem
Programm nicht aktiv.
; In allen Fällen wird ein Sprung zum
Programm mit dem Namen
; "main" ausgeführt.
; RJMP heisst "Relative Jump" oder relativer
Sprung. Bei dem rela-
; tiven Sprung wird in dem Befehlswort eine
relative Distanz mit
; angegeben, die der Assembler aus
der Differenz zwischen der Adresse
; des Ziels (main) und der aktuellen Adresse ausrechnet. Die Sprung-
; Distanz darf 2 kB vorwärts oder rückwärts nicht überschreiten
und
; es gibt Fehlermeldungen.
RJMP main
; Hier beginnt das Hauptprogramm mit dem Namen "main". Als erstes
; muss deshalb ein sogenanntes Label gesetzt werden. Ein Label ist
; ein frei definierter Name, gefolgt von einem Doppelpunkt. Zur
; besseren Übersicht beginnen alle Label in
Spalte 1 einer Zeile,
; alle Programmbefehle jedoch mit einem oder mehr Leerzeichen oder TAB.
; Hinter dem Label kann schon ein Programmbefehl stehen, getrennt
; mittels Leerzeichen oder TAB. Habe ich aber hier nicht gemacht.
main:
; Als erstes muss der Port B, an den
die LEDs angeschlossen sind, als
; Ausgang definiert werden. Dies macht man, indem man acht Einsen in
; das Datenrichtungs-Register des Ports B schreibt. Das Datenrichtungs-
; Register von Port B heisst DDRB (Data
Direction Register B). Das er-
; fordert zwei Schritte: Erstens wird der Binärwert 1111.1111 in
ein
; Register geschrieben:
LDI mp,0b11111111
; Der Befehl LDI (LoaD Immediate) lädt
einen 8-Bit-Wert in
das Register
; mp. Dieser Befehl ist nur für die Register R16 bis R31 zulässig, des-
; halb ist mp am Programmanfang als Register R16 definiert worden. Die
; Befehle mit zwei Parametern sind durchgängig so aufgebaut, dass der
; erste Parameter (Register mp) immer das Ziel angibt, in
dem das Ergeb-
; nis gespeichert wird. Nach der Durchführung dieses Befehls enthält
; das Register 16 den Binärwert 11111111, hexadezimal FF oder dezimal
; 255.
; Die Schreibweise "0b..." kennzeichnet immer eine Binärzahl, mit "0x..."
; wird eine Hexadezimalzahl angegeben. Die führende Null lässt den
; Assembler eine gültige Zahl
erwarten. Zahlen ohne diesen Vorsatz
sind
; automatisch dezimal ( LDI mp,255 wäre
gleichwertig).
; Dieser Wert muss jetzt in das Datenrichtungs-Register
gegeben
; werden, damit der Port B in
ganzer Breite zu Ausgängen wird. Eine 1
; im Datenrichtungsregister macht den zugehörigen Pin zum Ausgang, eine
; 0 zum Eingang.
OUT DDRB,mp
; Der Befehl OUT schreibt Registerinhalte
(hier: mp oder R16) auf einen
; Port (hier DDRB). DDRB ist in
der Datei "8515def.inc" definiert, die
; über den .DEVICE-Befehl oder wie
hier über den .INCLUDE-Befehl in
den
; Assembler-Text eingebunden ist.
Dadurch muss man sich die Portnummer
; des Datenrichtungsregisters nicht merken.
; Dieser Programmteil gibt nun abwechselnd Nullen und Einsen auf die
; Portausgänge aus. Die LEDs leuchten in
einem sehr schnellen Takt.
; Da dieser Programmteil unendlich lang wiederholt ist, kriegt er das
; Label loop, da nach dem Klappern der Bits
wieder dorthin gesprungen
; werden muss.
loop:
LDI mp,0x00
OUT PORTB,mp
; LDI lädt erst mal acht Bits
Nullen in das Universalregister mp.
; OUT gibt diese Nullen auf dem Port
B aus. Diesmal kommen sie in das
; Datenausgaberegister von Port B (PORTB).
; Die Nullen lassen die LEDs leuchten, da sie über 1 k an die Versor-
; gungsspannung geführt sind (0=an, 1=aus).
LDI mp,0xFF
OUT PORTB,mp
; Anschliessend kommen acht Einsen in das Register
und von da aus in
; den Datenausgabe-Port. Das macht die Lämpchen wieder aus.
RJMP loop
; Mit diesem relativen Sprung geht es wieder zurück an den Anfang der
; Schleife, und das Ganze dauert ewiglich.
; Bei 4 MHz Quarzfrequenz dauert jeder LDI-
und OUT-Befehl in
der Schleife
; 250 ns, der RJMP braucht zwei Takte und
dauert 500 ns. Macht zusammen
; 1500 ns, die LEDs werden folglich mit 667 kHz angesteuert.
; Nach dem Assemblieren sollte das Programm acht Worte haben. In
der
; Datei TEST1.LST kann man sich das Ergebnis der Assemblierung an-
; schauen.
; Dieses war der erste Streich ...
©2002 by http://www.avr-asm-tutorial.net