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