
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?
Lesezeichen