YES!! \/
Geht nun endlich
Hier der komplette Code:
Code:
;Programm
;CDurTonleiter rauf spielen
.include "m8def.inc"

.def tmp = r16               	;Mein Universallregister
.def tonwert = r17				;aktueller Wert für den Ton
.def tonleiterEnde = r18		;Hier wird gespeichert, ob die Tonleiter schon
								;bis zu Ende gespielt wurde
.def lpm_reg = r0				;Mein lpm-Register

.equ Summer = PB2				;Summer an B.2
.equ time0 = 256-255			;Timer0 für die Tonleiter
.equ time1 = 65536-1800			;Damit wird der Timer1 vorgeladen, für die Sekunde
.equ daten_laenge = 7			;Anzahl der Werte

.org 0x000
   	rjmp reset					;Interruptvektor "reset:"

.org OVF1addr
	rjmp pruefSek				;Interruptvektor "pruefSek:"

.org OVF0addr
	rjmp timerSummer			;Interruptvektor "timerSummer:"

reset:
   	;Stack einrichten
   	ldi tmp, HIGH(RAMEND)      	;HIGH-Byte der obersten RAM-Adresse
   	out SPH, tmp
   	ldi tmp, LOW(RAMEND)      	;Low-Byte der obersten RAM-Adresse
   	out SPL, tmp

	;Timer Register für Ton werden belegt, hier Timer 0
	ldi tmp, (1<<CS02)			;Prescaler ist 256
	out TCCR0, tmp				;Register TCCR0 ist für den Prescaller zuständig
	ldi tmp, time0				;Hier wird der Timer vorgeladen
	out TCNT0, tmp

	;Timer Register für Sekunde werden belegt, hier Timer 1
	ldi tmp, (1<<CS12) | (1<<CS10)	;Prescaler ist 1024
	out TCCR1B, tmp
	ldi tmp, HIGH(time1)			;Für den Timer1 (16Bit) benötigen
	out	TCNT1H, tmp					;wir 2 Register, in denen wir den Wert
	ldi tmp, LOW(time1)				;für die 1 Sekunde (10000) speichern ->
	out TCNT1L, tmp					;"TCNT1H" und TCNT2L"

	ldi tmp, (1<<TOIE0) | (1<<TOIE1);Hier werden Interrupts nach Timer0 Überlauf eingeschaltet
	out TIMSK, tmp				;Register TIMSK ist dafür zuständig

	;Z-Register mit DB "tonleiter1" füllen
   	ldi ZH, HIGH(tonleiter1 * 2)
   	ldi ZL, LOW(tonleiter1 * 2)	
	
	sbi DDRB, Summer			;B.2 als Ausgang
	sbi PORTB, Summer			;B.2 auf HIGH stellen	

	ldi tonleiterEnde, 0b00000000	;tonleiterEnde auf 0 stellen

   	sei                    		;Interrupts zulassen

;Die Hauptschleife, die sich immer wiederholt und den Tonwert neu einliest
main:
	lpm                  		;Daten von tonleiter1: holen 
   	mov tonwert, lpm_reg   		;erstes Byte in tmp verschieben - ersten Tonwert speichern
	rjmp main					;immer wieder zurück zu main springen

;Läuft Timer1 über, so wird erstmal geprüft, ob der letzte Ton
;erreicht ist und der Timer1 wird neu vorgeladen
pruefSek:
	push tmp					;tmp sichern
	in tmp, SREG
	push tmp					;SREG sichern
		ldi tmp, HIGH(time1)	;Für den Timer1 (16Bit) benötigen
		out	TCNT1H, tmp			;wir 2 Register, in denen wir den Wert
		ldi tmp, LOW(time1)		;für die 1 Sekunde speichern ->
		out TCNT1L, tmp			;"TCNT1H" und TCNT2L"
			lpm                  		;Daten von tonleiter1: holen 
			sbrc tonleiterEnde, 0	;Ist tonleiterEnde = 0?
			rjmp subtrahiereZ	;Wenn tonleiter = 1, dann subtrahiere Z um 1

addiereZ:
	adiw ZL, 1            		;Z um 1 erhöhen
	rjmp pruefSek2				;zu "pruefSek2:" springen

subtrahiereZ:
	sbiw ZL, 1 					;Z um 1 erniedrigen

pruefSek2:
	ldi tmp, LOW  ((tonleiter1 * 2) + daten_laenge)	;vergleiche LOW-Byte 
   	cp ZL, tmp 
	ldi tmp, HIGH ((tonleiter1 * 2) + daten_laenge)	;vergleiche HIGH-Byte 
	cpc ZH, tmp 
	brne pruefTonrueckwaerts						;zu "pruefTonaus:" springen
	sbr tonleiterEnde, 1							;Hilfsvariable.1 auf 1 setzen
	
pruefTonrueckwaerts:
	sbrc tonleiterEnde, 1							;Ist tonleiter.1 = 0?
	rjmp regwiederholen								;Wenn NEIN, dann zu "regiwederholen:"
													;Wenn JA, dann prüfen, ob erster Ton
													;wieder geladen wurde
prueftonaus:
	ldi tmp, LOW  (tonleiter1 * 2 - 1)					;vergleiche LOW-Byte 
   	cp ZL, tmp 
	ldi tmp, HIGH (tonleiter1 * 2 - 1)					;vergleiche HIGH-Byte 
	cpc ZH, tmp
	brne regwiederholen
	ldi tmp, (0<<CS02)      						;JA -> Timer0 abstellen
	out TCCR0, tmp

regwiederholen:
	pop tmp
	out SREG, tmp				;SREG wiederholen
	pop  tmp					;tmp wiederholen
	reti

;Läuft Timer0 über, so wird B.2 umgeschaltet, sodass Ton
;aus dem Summer zu hören ist
timerSummer: 
   push tmp               		;tmp sichern 
   in tmp, SREG 
   push tmp 					;SREG sichern
	  sbis PINB, Summer         ;ist B.2 = 1?
      rjmp timerSummer1			;NEIN -> spring zu "timerSummer1:"
      cbi PORTB, Summer         ;JA -> setze B.2 auf 0 
	  rjmp timerSummer2		;springe zu "timerSummer2:"

timerSummer1:
	sbi PORTB, Summer			;B.2 auf 1 setzen

timerSummer2: 
		out TCNT0, tonwert		 ;Timer0 neu vorladen
   pop tmp                 		 ;SREG wiederholen 
   out SREG, tmp 
   pop tmp                 		 ;tmp wiederholen 
   reti

;Das sind die Werte, womit der Timer0 (Tonleiter-Timer) vorgeladen wird
;Anzahl der Wert muss GERADE sein
tonleiter1:
	.db 256-55, 256-49, 256-44, 256-41, 256-37, 256-33, 256-29, 256-27
Musste allerdings bei der Prüfung, ob der erste Ton wieder erreicht ist eine 1 abziehen, sonst hät er einen Ton zu früh aufgehört.
Wäre nett, wenn mir noch eine sagen könnte, ob er nun immer noch so unübersichtlich ist.
Und ein Bedenken hab ich noch. Meine Interruptroutine für Timer1, also wo er zu "pruefSek" springt, ist die nicht zu lang?

Zitat Zitat von izaseba
übe mal mit den cp cpc sub sbc und add adc Befehlen .
Werd ich machen, danke.

Gruß
Thomas