so mal wieder was von mir ....
Wie schon angekuendigt, wollte ich ohne Interrupt ein Programmcode schreiben.
Dabei sollen die LEDs mit dem jeweils auf dem STK500 befindlichen Taster geschaltet werden.
Also druecke Taste - jeweilige LED wird je nach vorherigen Zustand umgeschaltet.
LED an wird LED aus
LED aus wird LED an

Ablauf:
Im Programm selbst frage ich in der MAIN den TastenPort ab und lese den Inhalt in ein 1 Register,
invertiere dieses und schiebe den Inhalt in ein 2. Register.
Teste dann ob Taste gedrueckt ist, wenn ja springe in Warte und zaehle dort ein Register runter,
danach(RE_TEST) lese erneut den TastenPort in das 1. Register aus invertiere den Inhalt,
vergleiche dann mit Inhalt des 2. Registers(erstes Auslesen), wenn gleich springe zu LED_TOGGLE.
In LED_TOGGLE wird der LED_PORT in das LED_Stat-Register gelesen.
Nun wird mittels Exklusiv-ODER das LED_Stat-Register mit dem TAST_Stat-Register umgeschrieben.
LED=1 Tast=1 == LED=0
LED=0 Tast=0 == LED=0
LED=0 Tast=1 == LED=1
LED=1 Tast=0 == LED=1
Dann wird der Inhalt des LED_Stat an den LED_PORT ausgegeben.
Als naechstes wird nun ueberprueft, ob die gedrueckte Taste noch immer gedrueckt ist.
Falls das sein sollte kommt der Sprung in eine Schleife, die permanent die Tasten abfragt, bis die urspruenglich gedrueckte Taste losgelassen wurde.
Wenn das passiert kommt der Sprung zurueck in die MAIN, wo das Spiel wieder von vorn beginnen kann.
Hier nun der Code...

Code:
;***** STK500 Lernprogramm Nr.4
;*** Aufgabe: die der jeweiligen Taste zugeordnete LED auf dem STK500 schalten
;*** 1. Tastendruck: LEDs einschalten
;*** 2. Tastendruck: LEDs ausschalten
;*** zum Entprellen soll kein Interrupt werden 
;*** 
.include "m8515def.inc" 
.def Temp       = r16			; Temporary register 
.def Tast_Stat  = r17			; Tasten Status
.def Tast_Stat1 = r18
.def LED_Stat   = R19			; LED Status
;
.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 
   reti                        ;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 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 
	


MAIN:
	in Tast_Stat, TAST_PIN			; lese von PinD und speicher den Inhalt in Tast_Stat
	com Tast_Stat				; invertiert fuer spaetere EOR-Berechnung
	mov Tast_Stat1, Tast_Stat		; schiebe den Inhalt von Tast_Stat in Tast_Stat2
	cpi Tast_Stat, 0b00000000		; vergleiche Tast_Stat mit 0b00000000, wenn ungleich (Taste gedrueckt) springe zu 

WARTE
	brne WARTE
rjmp MAIN

WARTE:
	push r25						; Register auf Stack sichern
	in r25, SREG
	push r25

	WARTE_0:						; Wartezeit zum Entprellen
	dec r25							; Schleife decrement Register 25
	cpi r25, 0b00000000
	breq WARTE_ZEIT_EXIT
	rjmp WARTE_0

	WARTE_ZEIT_EXIT:				        ; Ausgang aus Warteschleife
	pop r25							; Register vom Stack holen
	out SREG, r25
	pop r25
	
	RE_TEST:				; 2. Test - Vergleich ob Taste noch immer gedrueckt
	in Tast_Stat, TAST_PIN			; erneute Abfrage von Tasten und Vergleich mit erster Abfrage
	com Tast_Stat				; invertiert fuer spaetere EOR-Berechnung
	cp Tast_Stat, Tast_Stat1		; wenn gleich, springe zu LED_TOGGLE
	breq LED_TOGGLE

rjmp MAIN

	LED_TOGGLE:				; schaltet LED um
	in LED_Stat, LED_PORT			; lese LEDs aus und speichere in LED_Stat
	eor LED_Stat, Tast_Stat			; ExclusivODER - schalte die Ausgaenge , wo Tasten gedrueckt werden um
									; LED=1 Tast=1 == LED=0
									; LED=0 Tast=0 == LED=0
									; LED=0 Tast=1 == LED=1
									; LED=1 Tast=0 == LED=1
	out LED_PORT, LED_Stat
	cp Tast_Stat, Tast_Stat1		; vergleiche ob Taste losgelassen
	breq WARTE2				; wenn nicht losgelassen, springe in WARTE2

rjmp MAIN

; Abfrage von Tasten und Vergleich ob die urspruenglich gedrueckte Taste noch immer gedrueckt ist
; neu gedrueckte Taste wird waehrend die urspruenglich gedrueckte Taste noch gedrueckt ignoriert
; ist urspruenglich gedrueckte Taste gedrueckt wird die Schleife nicht verlassen
WARTE2:
	RE_TEST_2:						
	in Tast_Stat, TAST_PIN			
	com Tast_Stat				; invertiert fuer spaetere EOR-Berechnung
	and Tast_Stat, Tast_Stat1		; Bitmaske - urspruenglich gedrueckte Taste
	cp Tast_Stat, Tast_Stat1
	breq WARTE2

rjmp MAIN
PS.
Einen Zustand habe ich nun noch nicht bedacht.
Es kann keine weitere Taste gedrueckt werden, solange die erste Taste nicht losgelassen wurde.
Das ist von mir in dem Programm zwar so gewollt, weil ich mir noch ueber die Ausfuehrung noch nicht Gedanken gemacht habe.
Haette ich das im jetzigen Code nicht verriegelt, wueder mir die weitere Taste, die erste LED wieder umschalten.

Eine Frage noch an die Experten:
Kann man im AVR-Studio die Zeilennummern aktivieren?
-> es macht die Fehlersuche leichter