Zitat Zitat von Florian
@ Thomas:
Warum hast Du TCNT0 mit time0 255-90 vorgeladen?
Weil ich den Prescaler nun auf 1024 habe und so besser auf eine Sekunde komme. Jede Sekunde soll er also nun den nächsten Ton laden. Hier der Code.
Code:
;Programm
;CDurTonleiter rauf und runter spielen
.include "m8def.inc"

.def tmp = r16               	;Mein Universallregister
.def zaehlerSek = r17			;Mein Zählregister
.def zaehlerTon = r18			;Mein Zählregister, um zu prüfen, ob alle Töne geladen wurden
.def lpm_reg = r0				;Mein lpm-Register

.equ time0 = 256-90				;Damit wird der Timer0 vorgeladen
.equ daten_laenge = 4			;Anzahl der Werte

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

.org OVF2addr
	rjmp pruefSek				;Interruptvektor "ladeTon:"

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 werden belegt, hier Timer 0
	ldi tmp, (1<<CS02) | (1<<CS00)	;Prescaler ist 1024
	out TCCR0, tmp				;Register TCCR0 ist für den Prescaller zuständig
	ldi tmp, time0				;Hier wird der Timer vorgeladen
	out TCNT0, tmp
	ldi tmp, (1<<TOIE0)			;Hier werden Interrupts nach Timer0 Überlauf eingeschaltet
	out TIMSK, tmp				;Register TIMSK ist dafür zuständig

	;Z-Register mit daten1 füllen
   	ldi ZH, HIGH(tonleiter1 * 2)
   	ldi ZL, LOW(tonleiter1 * 2)

	ldi zaehlerSek, 0b00000000	;ZählerSek auf 0 setzen		

   	sei                    		;Interrupts zulassen

main:
	cpi zaehlerSek, 0b00010100	;wenn ZählerSek != 40 ist
	brne main					;dann immer wieder zu "main:" springen

pruefTonleiter:
	clr zaehlerSek				;Zähler auf 0 setzen
	cpi zaehlerTon, 0b11111111	;Wenn ZählerTon != 255 ist
	brne ladeTon				;dann spring zu "ladeTon:"
	rjmp main					;sonst wieder zurück zu "main:"

pruefSek:
	push tmp					;tmp sichern
	in tmp, SREG				;SREG sichern
	push tmp
		inc zaehlerSek			;ZählerSek um 1 erhöhen
		ldi tmp, time0			;Hier wird der Timer vorgeladen
		out TCNT0, tmp
	pop tmp						;SREG wiederholen
	out SREG, tmp
	pop tmp						;tmp wiederholen
	reti						;wieder dahin, wo du hergekommen bist

ladeton:
	clr zaehlerSek				;Zähler wieder auf 0 setzen
	lpm						;Daten von tonleiter1: holen
	mov tmp, lpm_reg		;erstes Byte in tmp verschieben
	adiw ZL,1				;Z um 1 erhöhen, nächstes Byte
	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
	breq endeTon			;springe zu "endeTon:", wenn letztes Byte ausgelesen
	rjmp main				;wieder zurück zur "main:"

endeTon:
	ldi zaehlerTon, 0b11111111	;ZählerTon auf 255 setzen -> keine weiteren Wert
								;mehr von "tonleiter1:" holen
	rjmp main					;wieder zurück zu "main:"

tonleiter1:
	.db 28, 16, 14, 0			;Werte zum Vorladen des Timers für die Töne
								;c', a' und c''
Bitte auch prüfen, ob ich das Sichern von tmp und SREG über den Stack richtig gemacht habe, nicht das es hinterher daran liegt.
Also das Programm macht nun folgendes:
Er zählt hoch bis 1 Sekunde, dann prüft er, ob alle Töne schon geladen worden sind, wenn nicht, lädt er den nächsten Ton. Ist er beim letzten Ton angekommen, setzte er ein Register auf 255 und somit weiß ich dann, dass alle Töne geladen worden sind.

Hoffe mal, das ist das was du wolltest

Gruß
Thomas

[edit]
Wir wollen keine Sekunde erzeugen? Aber wenn wir eine Tonleiter machen, dann muss doch irgendwo festgelegt sein, in welchem Abstand der neue Ton kommen soll, oder?