Hallo mare_crisium,
wollte eigentlich mit diesem Post das fertige Programm praesentieren.
Leider bin ich da noch auf ein seltsames Problem gestossen:
Ich habe deshalb den Code von Dir, ohne meine Erweiterungen, im Simulator laufen lassen.(Nur Deine Kommentare asm-konform veraendert)
Beim 2. Anspringen der ISR(Simulator steht in Zeile 62 "rjmp TIMER1_COMPA_ISR") wird der Eingang PinD5 von High auf Low umgeschaltet.

edit: Stimmt nicht ganz, das Umschalten passiert schon vorher bei Counter 269 - bevor die ISR angsprungen wird. Genau bei Ueberlauf des Timers auf 1.

Leider kann ich mir nicht erklaeren, wie es dazu kommt...
Koenntest Du den Code versuchsweise in Deinem Simulator laufen lassen?
Code:
;***** STK500 Lernprogramm Nr.4e 
;*** Aufgabe: die Taste an PinD0 schaltet die zugeordnete LED auf dem STK500 
;*** 1. Tastendruck: LEDs einschalten 
;*** 2. Tastendruck: LEDs ausschalten 
;*** eine Timerroutine liest den TastenStatus ein 
;*** zum Entprellen - muss die TimerRoutine 3mal hintereinander den gleichen Wert, 
;*** einlesen um einen Tastzustand zu erkennen, Zst_Var 0x03 bzw. 0x00 
;*** Taste nicht gedrueckt >>> log 0 in Tast_Stat(r17) 
;*** Taste gedrueckt       >>> log 1 in Tast_Stat(r17) 
; 
; 
.include "m8515def.inc" 
.def Temp        = r16         ; Temporary Register 
.def Tast_Stat   = r17         ; Tasten Status 
.def Tast_Stat0    = r18 
.def LED_Stat    = r19         ; LED Status 
.def Zst_Var     = r20         ; Zustandsvariable - beinhaltet eine 2Bit-Zahl zur Tastzustandserkennung 
.def LED_Update_SPRR = r21      ; Sperrt die Ausfuehrung von TastenTest wenn, keine neuer TIMER1_OVL voran gegangen    
; 
.equ Timerwert   = 255 ;-1562        ; Timerschritte bis zum Überlauf 

.equ LED_PORT = PORTB         ; LEDs 
.equ LED_DDR  = PORTB-1         ; DataDirectory fuer LEDs 

.equ TAST_PORT= PORTD         ; Tasten 
.equ TAST_DDR = PORTD-1         ; DataDirectory fuer TastenEingang 
.equ TAST_PIN = PORTD-2         ; TastenEingang 


; Bit-Definitionen für Z-Wert 
.equ bZWERT_FLANKE = 3      ; Bit3 speichert das "Flankenbit" 
                     ; 0 = "keine Flanke" 
                     ; 1 = "Flanke steht an" 
.equ bZWERT_BETAETIGT = 0   ; Bit0 speichert den Tastenzustand 
                     ; 0 = "nicht betätigt" 
                     ; 1 = "betätigt" 

; Pinzuordnung für div. Tasten 
.equ TASTE0_PIN   = 0 
.equ TASTE1_PIN = 1 
.equ TASTE2_PIN = 3         ; die Zuordnung der PINs muss ja nicht mit der TastenNr übereinstimmen! 
.equ TASTE3_PIN = 2 

; jetzt kommen die Register, die die Z-Werte der Tasten enthalten. Im Prinzip 
; braucht man nur jeweils nur ein Nibble pro Taste. Um die Sache erstmal einfach 
; zu halten wird für jede Taste ein ganzes Byte verbraucht. 
.def rTASTE0_ZST = r15   ; enthält Zustand Taste0 
.def rTASTE1_ZST = r14   ; enthält Zustand Taste1 
.def rTASTE2_ZST = r13   ; enthält Zustand Taste2 
.def rTASTE3_ZST = r12   ; enthält Zustand Taste3 



; 
;   Vektortabelle 
; 
   rjmp RESET                 ;  1 - $000 RESET      External Pin, Power-on Reset, Brown-out, Reset and Watchdog Reset 
   reti                       ;  2 - $001 INT0       External Interrupt Request 0 
   reti                       ;  3 - $002 INT1       External Interrupt Request 1 
   reti                       ;  4 - $003 TIMER1 CAPT Timer/Counter1 Capture Event 
   rjmp TIMER1_COMPA_ISR        ;  5 - $004 TIMER1 COMPA Timer/Counter1 Compare Match A 
   reti                       ;  6 - $005 TIMER1 COMPB Timer/Counter1 Compare Match B 
   reti                       ;  7 - $006 TIMER1 OVF Timer/Counter1 Overflow 
   reti                       ;  8 - $007 TIMER0 OVF Timer/Counter0 Overflow 
   reti                       ;  9 - $008 SPI,       STC   Serial Transfer Complete 
   reti                       ; 10 - $009 USART,     RXC USART, Rx Complete 
   reti                       ; 11 - $00A USART,     UDRE USART Data Register Empty 
   reti                       ; 12 - $00B USART,     TXC USART, Tx Complete 
   reti                       ; 13 - $00C ANA_COMP   Analog Comparator 
   reti                       ; 14 - $00D INT2       External Interrupt Request 2 
   reti                       ; 15 - $00E TIMER0     COMP Timer/Counter0 Compare Match 
   reti                       ; 16 - $00F EE_RDY     EEPROM Ready 
   reti                       ; 17 - $010 SPM_RDY    Store Program memory Ready 
; 
TBL_UEBERGANG_01: 
.dw 0x0008  ; Tabellenlänge 
;                        T = 0               T = 1 
.dw 0x0200  ;     Z=0 ->      Z=0,Flanke=0     /     Z=2,Flanke=0 
.dw 0x0308  ;     Z=1 ->      Z=0,Flanke=1     /     Z=3,Flanke=0 
.dw 0x0400  ;     Z=2 ->      Z=0,Flanke=0     /     Z=4,Flanke=0 
.dw 0x0501  ;     Z=3 ->      Z=1,Flanke=0     /     Z=5,Flanke=0 
.dw 0x0602  ;     Z=4 ->      Z=2,Flanke=0     /     Z=6,Flanke=0 
.dw 0x0703  ;     Z=5 ->      Z=3,Flanke=0     /     Z=7,Flanke=0 
.dw 0x0F04  ;     Z=6 ->      Z=4,Flanke=0     /     Z=7,Flanke=1 
.dw 0x0705  ;     Z=7 ->      Z=5,Flanke=0     /     Z=7,Flanke=0 

; verweist auf den Programmspeicher und zeigt dort im ersten Wort auf den ersten 
; definierten Wert(Tabellenlaenge), 
; anschliessende Worte beinhalten die festgelegten Werte fortlaufend 
; bedeutet in meinem Fall Verweis auf 0x0011 mit 08 00 (.dw 0x0008) 
;                             0x0012 mit 02 00 (.dw 0x0200) 
;                             0x0013 mit 00 00 (.dw 0x0000) 
;                             0x0014 mit 04 00 (.dw 0x0400) 
;                             0x0015 mit 08 50 (.dw 0x0580) 
;                             0x0016   mit 02 87 (.dw 0x8702) 
;                              0x0017 mit 03 07 (.dw 0x0703) 
;                             0x0018 mit 00 00 (.dw 0x0000) 
;                             0x0019   mit 05 07 (.dw 0x0705) 
;          ->>> 
;          Der Wert(Tabellenlaenge) ist auch nur ein festgelegter Wert und fuer Programmoperationen wichtig. 
;          
RESET: 
; 
   ldi r16, LOW(RAMEND)           ;Stack initialisieren 
   out SPL, r16 
   ldi r16, HIGH(RAMEND) 
   out SPH, r16 
; 
   ldi temp,(1<<CS10)|(1<<WGM12)            ; Taktfrequenz Vorteiler 1 gewaehlt (fuer Simaulatortest)          
;   ldi temp,(1<<CS10)|(1<<CS12)|(1<<WGM12)   ; Taktfrequenz mit Vorteiler 1024 gewaehlt            
    out TCCR1B,temp 
; 
    ldi temp,HIGH(Timerwert) 
   out OCR1AH,temp 
    ldi temp,LOW(Timerwert) 
   out OCR1AL,temp 
; 
   ldi temp,(1<<COM1A1)|(0<<COM1A0) 
   out   TCCR1A,temp 
   ldi temp,(1<<OCIE1A)            ; Timer1 Overflow aktivieren 
   out TIMSK,temp          
; 
   clr Temp                ;Temp mit 0b00000000 bzw. 0x00 laden 
   out TAST_DDR, Temp      ;PORTD als Eingang 
   ser Temp                ;Temp mit 0b11111111 bzw. 0xFF laden 
   out TAST_PIN, temp      ;STK500 schaltet gegen GND - Taste gedreuckt (Pin==0) 
   out TAST_PORT, temp     ;PullUp an PortD einschalten 
   out LED_DDR,Temp        ;PORTB als Ausgang 
   out LED_PORT, temp      ;PORTB (LEDs) aus 
    
; Tastenzustände aller Tasten auf Null setzen 
   clr r16               ; 
   mov rTASTE0_ZST,r16      ; Taste0 und Taste1 zurücksetzen 
   mov rTASTE2_ZST,r16      ; Taste2 und Taste3 zurücksetzen 
   clr Zst_Var 
; 
   sei 
; 
; 
MAIN: 
   sbrc LED_Update_SPRR,0   ; kein LED_Update, wenn Bit0 ==0 
   rcall LED_Update 
   rjmp MAIN 
; 
LED_Update: 
   cbr LED_Update_SPRR,0   ; loesche Bit0, um LED_Update bis zur naechsten TIMER1_ISR zu sperren 
   ret 
; 

;/*------------------------------------- 
;
;INTERRUPTDIENST TIMER1_COMPA_ISR 
;
;Die Interruptdienstprogramm TIMER1_COMPA_ISR wird vom Output-Match-Interrupt von 
;Timer1 ausgelöst. Es liest die aktuellen Messwerte der Tasten vom TAST_PIN ab und 
;berechnet für jede Taste den neuen Zustand (Z-Wert). 
;
;Eingansgrössen: 
;   keine 
;
;Ausgangsgrössen: 
;   keine 
;
;geänderte Register 
;   keine 
;
;Anzahl Zyklen 
;
;*/ 

TIMER1_COMPA_ISR: 
   push r25 
   in r25,SREG 
   push r16 
   push r17 
   push r18 
   push zl 
   push zh 

;/* 
;Das hier hattest Du übersehen: 
;Der Zeiger auf die Übergangstabelle muss VOR (!!) dem Aufruf von NEXT0_TAST_ZST 
;in die Register zh:zl geladen werden !! 
;*/ 
   ldi zl,LOW(TBL_UEBERGANG_01) ; zh:zl := Zeiger auf Übergangstabelle ... 
   ldi zh,HIGH(TBL_UEBERGANG_01) ; ...wird für NEXT0_TAST_ZST gebraucht 

; Betätigungszustand der Tasten einlesen und der Reihe nach verarbeiten 
   in r18,TAST_PIN      ; r18 := Messwerte aller Pins 

; Taste0 verarbeiten 
   bst r18,TASTE0_PIN   ; überträgt den Messwert von TASTE0_PIN ins T-Flag von SREG 
   mov r16,rTASTE0_ZST  ; r16 := Z-Wert Taste0 
   andi r16,0x07      ; "Flankenbit" löschen 
   rcall NEXT0_TAST_ZST ; Folgezustand für Taste0 in r16 berechnen 
   mov rTASTE0_ZST,r16   ; neuen Z-Wert in TASTE0_ZST speichern 

; Taste1 verarbeiten 
   bst r18,TASTE1_PIN   ; überträgt den Messwert von TASTE1_PIN ins T-Flag von SREG 
   mov r16,rTASTE1_ZST  ; r16 := Z-Wert Taste1 
   andi r16,0x07      ; "Flankenbit" löschen 
   rcall NEXT0_TAST_ZST ; Folgezustand für Taste1 in r16 berechnen 
   mov rTASTE1_ZST,r16   ; neuen Z-Wert in TASTE1_ZST speichern 

; usw... 

   sbr LED_Update_SPRR,0            ; Status fuer LED_Update 1 - LED_Update  / 0 - kein LED_Update 

   pop zh 
   pop zl 
   pop r18 
   pop r17 
   pop r16 
   out SREG,r25 
   pop r25 
   reti 
; 
;/*------------------------------------- 
;PROZEDUR NEXT0_TAST_ZST 
;
;Die Prozedur NEXT0_TAST_ZST liest den Folgezustand der Tastenentprellung aus einer 
;Übergangstabelle aus. Die Adresse der Tabelle wird in zh:zl übergeben. Der aktuelle 
;Zustand (Z-Wert) wird in r16 übergeben. Der aktuelle Tastenzustand (betätigt/nicht 
;betätigt) ist im T-Flag von SREG gespeichert. Das Ergebnis wird in r16 zurückgegeben. 
;Die Tabelle, darf maximal 127 Einträge enthalten. Der erste Eintrag der Tabelle ist 
;die Länge der Tabelle und dient der Bereichsüberprüfung. 
;
;D.h. der Zeiger auf die Übergangstabelle muss zh:zl geladen werden BEVOR diese 
;Prozedur aufgerufen wird!! In diesem Beispiel, bei dem nur eine einzige Übergangstabelle 
;im Spiel ist, könnte man zh:zl auch innerhalb von NEXT0_TAST_ZST laden. Um die 
;Prozedur auch in Programmen verwenden zu können, in denen mehrere Zustandsautomaten 
;nebeneinanderherlaufen, ist es sinnvoll, den Zeiger vorher zu laden. Dann kann je 
;nach Aufgabe eine andere Tabelle verwendet werden. Kommt in meinen Programmen öfters 
;vor ;-). ;
;
;Eingansgrössen: 
;   r16      : enthält aktuellen Z-Wert der Taste 
;   zh:zl   : enthält Zeiger auf die Übergangstabelle 
;   SREG (T-Flag) : enthält den aktuellen Messwert der Taste 
;      T = 0 : Taste nicht betätigt 
;      T = 1 : Taste betätigt 
;
;Ausgangsgrössen: 
;   r16      : enthält den neuen Z-Wert für die Taste 
;   zh:zl   unverändert 
;   SREG   unverändert 
;
;geänderte Register 
;   r16 
;
;Anzahl Zyklen 
;
;*/ 

NEXT0_TAST_ZST: 
   push r17 
   in r17,SREG 
   push r17 
   push r18 
   push zl 
   push zh 

; Zeiger auf Anfang der Übergangstabelle berechnen 
   add zl,zl        ; zh:zl verdoppeln, weil einer Adresse im... 
   adc zh,zh        ; .. Programmspeicher immer zwei Bytes entsprechen 
   ; FRAGE: Wo wird die Information abgelegt -> im Flashspeicher 
   ; 
   ; 
; Information in Bit7 löschen; Tabelle darf nicht länger als 127 Einträge sein 
   andi r16,0x7F    ; 

; Tabellenlänge einlesen (0-ter Eintrag in der Tabelle) 
   lpm r17,z+       ;  r17 := TBL_LNG einlesen 
   ; 1.Durchgang 
   ; es wird in R16 der Wert 0x19 eingetragen - ??? Die letzte Stelle in der Tabelle (0x0019) 
   ; und in R30(ZL) die 0x01 
   ; 
   ; 2.Durchgang 
   ; es wird in R16 der Wert 0x19 eingetragen - ??? Die letzte Stelle in der Tabelle (0x0019) 
   ; und in R30(ZL) die 0x01 
   ; 
   ; KLAR; Du hattest den Zeiger nicht gesetzt! 
   ; 
   ; 
   lpm r18,z+       ;  zweites Byte überlesen, wird nicht gebraucht 

; Bereichsprüfung ( r17 < TBL_LNG ) 
   cp r16,r17       ; Tabellenindex mit TBL_LNG vergleichen 
   brlt NXT0ZST_00  ; Sprung, wenn Tabellenindex iO 

; Fehler: Tabellenindex ist zu gross 
   clr r16 ; Zustand auf Null setzen 
   rjmp NXT0ZST_EXIT ; fertig 

NXT0ZST_00: 
; Tabellenindex im zulässigen Bereich 
   clr r17 ; 
   add zl,r16       ; Index zweimal zum Zeiger addieren, weil... 
   adc zh,r17       ; ... in der Tabelle... 
   add zl,r16       ; ... 2-Byte-Worte gespeichert sind. 
   adc zh,r17       ; zh:zl := Zeiger auf Tabelleneintrag    
   lpm r16,z+       ; r16 := Folgezustand für T=0 
   lpm r17,z        ; r17 := Folgezustand für T=1 
   brtc NXT0ZST_EXIT ; fertig, wenn T = 0 

; T = 1, d.h. Taste betätigt 
   mov r16,r17      ; zweiten Eintrag als Folgezustand verwenden 

NXT0ZST_EXIT: 
;   sbr LED_Update_SPRR,0            ; Status fuer LED_Update 1 - LED_Update  / 0 - kein LED_Update 
; diese Zeile gehört in den Interruptdienst! 

   pop zh 
   pop zl 
   pop r18 
   pop r17 
   out SREG,r17 
   pop r17 
   ret 
;