robo_wolf,
da hast Du Dir einen sehr guten und erfolgsversprechenden Zugang ausgesucht
! Ein paar Anmerkungen zu Deinem Programm:
Du musst bedenken, dass die Interrupt-Dienstprozedur INT0_ISR dieselben Register verwendet, wie das Hauptprogramm. Wenn also die Haupschleife MAIN mit bestimmten Registern etwas ausrechnen wollte, als der Interrupt sie unterbrach, dann erwartet sie, dass die Register bei der Rückkehr aus dem Interrupt wieder dieselben Werte haben wie vorher. Du musst also dafür sorgen, dass die Registerinhalte gleich zu Beginn von INT0_ISR auf den Stack gesichert (push rxx) und unmittelbar vor der Rückkehr (reti) wiederhergestellt (pop rxx) werden. Wichtig ist auch, den aktuellen Inhalt des SREG auf dem Stack zu sichern. Sonst gehen dem Hauptprogramm so wichtige Sachen wie der aktuelle Stand des Carry- oder Zero-Flags verloren. Also brauchst Du parallel zum Sichern der Register noch die Zeilen
Aus leidvoller (
) Erfahrung habe ich mir angewöhnt, vor jedem Unterprogramm und jedem Interruptdienst aufzuschreiben, welche Register wie verwendet werden. Z.B. so:
Code:
/*
Der Steuerblock und die Daten der FIFO werden im RAM angelegt.
Die Offsets der Steuerdaten sind
+0 : FIFO_FLAGS
+1 : FIFO_WR zeigt auf nächste Schreibposition
+2 : FIFO_RD zeigt auf nächste Leseposition
+3 : FIFO_CAP FIFO-Kapazität, maximal 255 Byte
Datenblock:
+4 : <1. Datenbyte>
Die Bedeutung der Bits in FIFO_FLAGS ist:
XXXX XXXX
||
|+------ 0: FIFO ist nicht voll
| 1: FIFO ist voll
|
+------- 0: FIFO ist nicht leer
1: FIFO ist leer
*/
;------------------------------------------
;
; FIFO-KONSTANTEN
;
; BYTE-OFFSETs
.equ FIFO_FLAGS = 0
.equ FIFO_WR = 1 ; zeigt auf nächste freie Position
.equ FIFO_RD = 2 ; zeigt auf nächste belegte Position
.equ FIFO_CAP = 3 ;
.equ FIFO_LNG = 4 ; Länge des Datenblocks
;BIT-OFFSETs
.equ FIFO_VOLL = 0
.equ FIFO_LEER = 1 ;
; Der Platzbedarf im RAM
; berechnet sich als
; FIFO_SIZE = FIFO_LNG + FIFO_CAP
/*------------------------------------------
PROCEDURE FIFO8_CREATE
erzeugt die Struktur einer leeren FIFO für 1-Byte-Daten im RAM
Eingangsvariablen
zh:zl: enhält den Zeiger auf die RAM-Adresse,
an der die FIFO angelegt werden soll
r16: enthält die FIFO-Kapazität
Ausgangsvariablen
zh:zl : enthält den Zeiger auf die FIFO
r16: enthält die FIFO-Kapazität
geänderte Register
keine
geänderte Ports
keine
*/
FIFO8_CREATE:
push r17
in r17,SREG
push r17
push r18
; FIFO-Steuerblock mit Nullen füllen
ldi r18,FIFO_LNG
clr r17
FIFO_CREAT01:
tst r18
breq FIFO_CREAT_00
st z+,r17
dec r18
rjmp FIFO_CREAT01
FIFO_CREAT_00:
; zh:zl wieder auf Anfang der FIFO stellen
sbiw zh:zl,FIFO_LNG
; Anfangszustand der Flags einstellen
ldi r17,(1<<FIFO_LEER); Flag "FIFO_LEER" setzen
std z+FIFO_FLAGS,r17
dec r16 ;
std z+FIFO_CAP,r16 ; FIFO-Kapazität speichern
inc r16 ;
pop r18
pop r17
out SREG,r17
pop r17
ret
Weiterhin viel Spass und viel Erfolg!
mare_crisium
Lesezeichen