Habe den Code zum Einlesen und Auswerten des an PinD0 befindenlicher Taste.
Einige Zeilen sind stark an mare_crisium´s "endlichen Zustandsautomaten" angelehnt.
Das Schalten der LED habe ich vorerst weggelassen.
Code:
;***** STK500 Lernprogramm Nr.4d
;*** 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(log 1) bzw. 0x00(log 0)
;*** 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 TOGGLE_SPRR = r21			; Sperrt die Ausfuehrung von TastenTest wenn, keine neuer TIMER1_OVL voran gegangen	

;
;	TimerWerte(bei 8MHz - ca. 0,2sec)
.equ Timerwert   = -60 			; Timerschritte bis zum Überlauf(fuer Simulatortest)
;.equ Timerwert   = -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
;
;***** 
;Reset and Interrupt vector    ;VNr.  Beschreibung 
   rjmp   RESET                ;1   POWER ON RESET 
   reti						   ;2   Int0-Interrupt 
   reti                        ;3   Int1-Interrupt 
   reti                        ;4   TC1 Capture 
   reti                        ;5   TC1 Compare Match A TC2 Overflow 
   reti                        ;6   TC1 Compare Match B TC1 Capture 
   rjmp  TIMER1_OVF            ;7   TC1 Overflow TC1 Compare Match A 
   reti	                       ;8   TC0 Overflow TC1 Compare Match B 
   reti                        ;9   SPI, STC Serial Transfer Complete TC1 Overflow 
   reti                        ;10  UART Rx Complete TC0 Overflow 
   reti                        ;11  UART Data Register Empty SPI, STC Serial Transfer Complete 
   reti                        ;12  UART Tx Complete UART Rx Complete 
   reti                        ;13  Analog Comparator 
   reti                        ;14  Int2-Interrupt 
   reti                        ;15  Timer 0 Compare Match 
   reti                        ;16  EEPROM Ready 
   reti                        ;17  Store Program Memory Ready 
;*****

RESET: 
	


	ldi temp,(1<<CS10)				; Taktfrequenz Vorteiler 1 gewaehlt (fuer Simaulatortest)          
;	ldi temp,(1<<CS10)|(1<<CS12)	; Taktfrequenz mit Vorteiler 1024 gewaehlt           
 	out TCCR1B,temp
									; Timer1 vorladen 
 	ldi temp,HIGH(Timerwert) 
	out TCNT1H,temp
 	ldi temp,LOW(Timerwert) 
	out TCNT1L,temp	
	ldi temp,(1<<TOIE1)				; Timer1 Overflow aktivieren

	out TIMSK,temp          





	ldi r16, LOW(RAMEND)        	;Stack initialisieren 
	out SPL, r16 
	ldi r16, HIGH(RAMEND) 
	out SPH, r16 

	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 
	clr Tast_Stat					;Tast_Stat auf def. Zustand
	clr Zst_Var
	sei								; globale Interruptfreigabe
MAIN:
	sbrc TOGGLE_SPRR,0				; kein TOGGLE, wenn Bit0 ==0
	rcall TOGGLE
	rjmp MAIN


TIMER1_OVF:
	push	TEMP					; TEMP auf Stack sichern
	in	TEMP,SREG					; SREG auf Stack sichern 
	push	TEMP					;
	
	in Tast_Stat0, PIND				; Tasten werden komplett eingelesen
	com Tast_Stat0					; invertiere
	clt								; loesche T-Flag
	SBRC Tast_Stat0,0				; RegisterBit0 von TastStat ==0 ueberspringe / T-Flag wird nicht gesetzt	
	set								; ==1 setze T-Flag
;	
;	default wird -1 in temp eingetragen | springt bei nicht gesetzten T-Flag zu TastZst0 
;	bei gesetzten T-Flag wird +1 in temp eingetragen
;
	ldi temp, 0x03					; temp == "-1"
	brtc TastZst0
	ldi temp, 0x01					; temp == "+1"
;
;	TastZustand0
;
	TastZst0:
	cpi Zst_Var,0x00				; vergleiche ob Zst_Var ==0
	brne TastZst1					; springe wenn ungleich
	sbrs temp, 0x01					; ueberspringe naechsten Befehl, wenn temp negativ(0x03) ist
	add Zst_Var, temp				; addieren temp in Zst_Var
	rjmp TastZst_Exit
;
;	TastZustand1
;
	TastZst1:
	cpi Zst_Var, 0x01				; vergleiche ob Zst_Var ==1
	brne TastZst2
	add Zst_Var, temp
	rjmp TastZst_Exit
;
;	TastZustand2
;
	TastZst2:
	cpi Zst_Var, 0x02				; vergleiche ob Zst_Var ==2
	brne TastZst3
	add Zst_Var, temp
	rjmp TastZst_Exit
;
;	TastZustand3					; Fehler abfangen Zst_Var darf nur Werte zwischen 0x00 und 0x03 haben
;
	TastZst3:
	cpi Zst_Var, 0x03				; vergleiche ob Zst_Var ==3
	brne TastZst_Error
	sbrc temp, 0x01
	add Zst_Var, temp
;
	TastZst_Error:
	;
	TastZst_Exit:
	andi Zst_Var, 0xFB				; eventuellen Uebertrag loeschen
;
	cpi Zst_Var, 0x00				; ueberspringe naechsten Befehl
	brne Test2
	cbr Tast_Stat,0x01				; >>>>>Taste nicht gedrueckt
;
	Test2:
	cpi Zst_Var,0x03				; ueberspringe naechsten Befehl 
	brne T0_OVL_Exit
	sbr Tast_Stat,0x01				; >>>>>Taste gedrueckt
;
	T0_OVL_Exit:
									; Timer1 vorladen 
 	ldi temp,HIGH(Timerwert) 
	out TCNT1H,temp
 	ldi temp,LOW(Timerwert) 
	out TCNT1L,temp	
;
	sbr TOGGLE_SPRR,0				; Status fuer TOGGLE 1 - TOGGLE / 0 - kein TOGGLE
	pop	TEMP						; 
	out	SREG,TEMP					; SREG zurueckschreiben
	pop	TEMP						; TEMP zurueckschreiben 
	reti


TOGGLE:
	cbr TOGGLE_SPRR,0				; loesche Bit0, um TOGGLE bis zum naechsten TIMER1_OVF zu sperren
	nop								; kommt spaeter
	ret
Ganz zufrieden bin ich damit nicht..
Es tut zwar was es soll, ABER:
- es wurden 5 Register dafuer benoetigt (schaem)
- ich bin mir nicht sicher, ob alles in der TimerServiceRoutine drin sein sollte ???
(hatte mal gelesen, das die Programmunterbrechungen so kurz wie moeglich sein sollten) bei mir spielt sich da fast alles ab.
- gern haette ich die von mare_crisium aufgestellte Zustandstabelle benutzt, nur leider verstehe ich deren Funktion nicht richtig (wieder schaem)
(Da braeuchte ich noch mal ein bischen Starthilfe...generell das Benutzen von arrays und deren Auswertung)
- mit dem Konzentrieren auf eine Taste PinD0 in diesem Beispiel, seh ich momentan kein einfaches Einbinden der restlichen 7 Tasten
- vom eigendlichen Ziel "IO-Treiber" bin ich noch sehr weit weg