| Befehl | Kommentar |
| | ;*** Beispielprogramm puls.asm *** |
| .INCLUDE "8515def.inc" | ;Binde Programmcode aus der Datei 8515def.inc ein. ;Enthält u. a. vordefinierte symbolische Namen ;z. B. für Register. [Info: .INCLUDE - 8515def.inc - Register] |
| .DEF Temp =R16 | ;Weise dem Register R16 den symbolischen Namen ;Temp zu (dient als Zwischenspeicher). [Info: .DEF - Register] |
| .DEF Taktzahl =R17 | ;Weise dem Register R17 den symbolischen Namen ;Taktzahl zu. ;Taktzahl enthält Zahl der Takte, nach denen ein ;Pulswechsel erzeugt wird. ;Wird durch den Logikpegel am Pin 0 ;von Port C dargestellt (Gehäuse-Pin 21). ;Damit wird eine LED angesteuert. [Info: .DEF] |
| .EQU PORTC_PULSBIT =0 | ;Setze symbolische Variable PORTC_PULSBIT=0. ;Unten wird Bit 0 (Pin 0) des Port C durch ;diese Variable auf 0 gesetzt. ;Löscht Puls-LED. [Info: .EQU] |
| .EQU TAKTE_PRO_PULS =16 | ;Setze symbolische Variable TAKTE_PRO_PULS=16. ;Pulszustands (LED an/aus) wird nach dieser ;Anzahl Counter-Interrupts geändert. [Info: .EQU] |
.CSEG .ORG 0x00 | ;Setze Beginn eines Code-Segments. ;.ORG setzt den Beginn hier ;auf den hexadezimalen Wert 0. [Info: .CSEG - .ORG] |
rjmp RESET rjmp RESET rjmp RESET rjmp RESET rjmp RESET rjmp RESET rjmp RESET rjmp PULS rjmp RESET rjmp RESET rjmp RESET rjmp RESET rjmp RESET | ;Hier stehen die Sprungbefehle, ;die zu den Programmteilen führen, die ;je nach Interrupt ausgeführt werden sollen. ;Wir benötigen für unser ;Programm nur den Timer-Interrupt. ;Er wird durch den Befehl rjmp PULS ;aufgerufen. Weiter unten steht nach ;dem Label PULS der Programmteil, zu ;dem gesprungen wird, wenn ;der Timer-Interrupt nach Ablauf der ;festgesetzten Zeit vom Mikrocontroller ;ausgelöst wird. ;Falls andere Interrupts ausgelöst ;werden sollten, würde das Programm ;in den Initialisierungsteil nach ;dem Label RESET springen. [Info: rjmp - Timer/Counter - Interrupt - Label] |
| .ORG 0x0d | ;Setze Adresszähler des aktuellen Segments ;auf den angegebenen Wert, hier hexadezimal ;0x0d. Das ist die Adresse nach den obigen ;Sprungbefehlen. [Info: .ORG] |
| RESET: | ;Label (Sprungmarke). ;Die meisten Interruptvektoren (oben) ;zeigen in diesem Beispiel auf das Label RESET. ;Bei den entsprechenden Interrupts wird ;in diesen Programmteil gesprungen. [Info: Label] |
ldi Temp, low(RAMEND) out SPL, Temp ldi Temp, high(RAMEND) out SPH, Temp | ;Die Startadresse des Stack (Stapelspeicher) ;wird festgelegt und der Stackpointer ;(Stapelzeiger) auf diesen Wert gesetzt. ;Die weitere Nutzung des Stack übernimmt ;in unseren Beispielprogramm der ;Mikrocontroller selbst. [Info: Stack - ldi - out] |
sbi DDRC, PORTC_PULSBIT sbi PORTC, PORTC_PULSBIT | ;Konfiguriere Pin 0 von Port C als Ausgabe. ;Setze Bit 0 in Port C auf 1. [Info: Port - sbi] |
ldi Temp, 5 out TCCR0, Temp
ldi Temp, 2 out TIMSK, Temp
ldi Taktzahl, TAKTE_PRO_PULS | ;Zähltakt=Systemtakt/1024. ;Jeder 1024ste Takt des Quarzoszillators ;erhöht den Inhalt des Zählregisters um 1.
;Freigabe der Timer/Counter-Interrupts
;Lade 16 (TAKTE_PRO_PULS) ;in das Register R17 (Taktzahl). [Info: Timer/Counter - ldi - out] |
| sei | ;Freigabe der Interrupts allgemein [Info: sei - Interrupt] |
ENDLOSSCHLEIFE:
rjmp ENDLOSSCHLEIFE | ;Diese Endlosschleife ruft mit dem Sprungbefehl ;rjmp sich ständig selbst auf. Die ;wesentlichen Aktionen unseres Programms ;finden im Programmteil PULS statt, ;der per Timer-Interrupt automatisch ;in kurzen Zeitabständen aufgerufen wird. [Info: Interrupt - Timer/Counter - Label - rjmp] |
| PULS: | ;Dieser Programmteil wird bei jedem ;Interrupt des Timer/Counter 0 ausgeführt. ;Hier wird die Pulsfrequenz gesetzt ;und entschieden, ob die LED mit 0 oder 1 ;angesteuert wird (an/aus). [Info: Timer/Counter - Label] |
dec Taktzahl brne ZURUECK | ;Verringere Inhalt der Variable Taktzahl um 1. ;Springe zur Sprungmarke ZURUECK (s. u.), ;falls Taktzahl noch nicht =0 ;(ansonsten werden die folgenden Befehle ;ausgeführt). ;D.h.: Nach jedem 16ten Interrupt werden ;die folgenden Programmzeilen ausgeführt. ;Dadurch wird die Blinkfrequenz verkleinert. [Info: dec - brne - Timer/Counter - Label] |
sbis PIND, 0 ldi Taktzahl, TAKTE_PRO_PULS/4 | ;Überspringe nächsten Befehl, ;falls Pin 0 von Port D = 1 (Gehäuse-Pin 10). ;Der symbolische Name PIND ist in der ;Datei 8515def.inc definiert. Über ;diese Adresse können die Logikpegel ;an den Pins von Port D gelesen werden. ;Setze Taktzahl auf TAKTE_PRO_PULS/4 (=16/4) ;Leuchtdiode blinkt 4 Mal schneller. [Info: sbis - ldi - 8515def.inc] |
sbic PIND, 0 ldi Taktzahl, TAKTE_PRO_PULS | ;Überspringe nächsten Befehl, ;falls Pin 0 von Port D = 0 (Gehäuse-Pin 10). ;Setze Taktzahl auf TAKTE_PRO_PULS (=16). [Info: sbic - ldi] |
sbis PORTC, PORTC_PULSBIT rjmp PULS_1 rjmp PULS_0 | ;Überspringe nächsten Befehl, falls Pulsbit=1. ;Springe zum Label PULS_1. ;Springe zum Label PULS_0. [Info: sbis - Label - rjmp] |
PULS_0: cbi PORTC, PORTC_PULSBIT rjmp ZURUECK | ;Label (Sprungmarke) ;Setze Pulsbit=0. ;Springe zum Label ZURUECK. [Info: cbi - rjmp - Label] |
PULS_1: sbi PORTC, PORTC_PULSBIT rjmp ZURUECK | ;Label (Sprungmarke) ;Setze Pulsbit=1. ;Springe zum Label ZURUECK. [Info: sbis - rjmp - Label] |
ZURUECK: reti | ;Label (Sprungmarke). ;Beende den Interrupt und ;Springe zurück in die Endlosschleife. [Info: reti - Label] |