Über dir, hehe ;)
Druckbare Version
Über dir, hehe ;)
Hallo Thomas!
Jetzt hast Du ja schon mehr gemacht, als Du solltest, das wäre die nächste Aufgabe gewesen! *lol*
Herzlichen Glückwunsch!
Mal sehn ob ich Fehler finde! ;o)
Hallo Thomas,
Ich sehe, Du hast es mit dem lpm Befehl begriffen, so wie ich sehe springst Du im
Sekundentakt die Datenbank durch, und wenn Du am ende angekommen bist gehst Du in eine Endlosschleife , richtig?
Ich denke, daß man aber mit den Zahlen, die Du mit lpm holst noch was füttern sollte.
Jo, so ist das erstmal richtig, wie du sagst.
Jo, die Zahlen die ich von der Datenbank hole, müssten irgendwie in einen zweiten Timer rein, der dann den Sound abspielt, ne?
Florian:
Du hast was von Timerinterrupt geschrieben, du bist schuld :P *g*Zitat:
Jetzt schriebe bitte den Code so um, dass immer bei jedem Timerinterrupt die Werte aus dem Datenregister nacheinander reingeladen werden!
Also irgendwie steige ich durch den Code nicht durch! *lol*
Thomas, es ist nicht schlimm,
damit hast Du durch den Rücken ins Auge geschossen!
Ausgelesen hast Du schon alles, dann versuche doch einen zweiten Timer, der Dir den Ton erzeugt damit zu laden, also bei jedem Sekundeninterrupt mit hilfe von lpm den Wert auslesen, und damit den Timer für den Ton zu stopfen,
Ist fast das gleiche, wie bei der Sirene, aber eben nur fast
Lol, auch net schlecht *g*Zitat:
Zitat von Florian
Ok, also ich werds versuchen mit dem zweiten Timer.
Argh, bei Timer2 gibt es gar kein Prescaler von 512, hrmph...muss ich die Timer tauschen....also Timer2 für die Sekunde und Timer0 für den Ton.
Na, wie sieht's aus?Zitat:
Ok, also ich werds versuchen mit dem zweiten Timer.
So, Update:
Aber bei der Zeile hier meckert er: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 Tonwert = r19 ;aktueller Wert für den Ton, damit wird der Timer0 vorgeladen
.def lpm_reg = r0 ;Mein lpm-Register
.equ Summer = PB2 ;Summer an B.2
.equ time0 = 256-255 ;Timer0 für die Tonleiter
.equ time2 = 256-90 ;Damit wird der Timer2 vorgeladen, für die Sekunde
.equ daten_laenge = 4 ;Anzahl der Werte
.org 0x000
rjmp reset ;Interruptvektor "reset:"
.org OVF2addr
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 512
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 2
ldi tmp, (1<<CS22) | (1<<CS21) | (1<<CS20) ;Prescaler ist 1024
out TCCR2, tmp ;Register TCRR2 ist für den Prescaller zuständig
ldi tmp, (1<<TOIE0) | (1<<TOIE2);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
sbi DDRB, Summer ;B.2 als Ausgang
sbi PORTB, Summer ;B.2 auf HIGH stellen
sei ;Interrupts zulassen
;Die Hauptschleife
main:
cpi zaehlerSek, 0b00010100 ;wenn ZählerSek != 40 ist
brne main ;dann immer wieder zu "main:" springen
;Wenn eine Sekunde um ist, dann springe hier rein
;und prüfe, ob es noch einen Wert für die Tonleiter
;zu laden gibt, wenn nicht, spring wieder zurück zu main
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:"
;Wird aufgerufen, wenn Timer2 überläuft (Timer für Sekunde)
;Hier wird das Zählregister für den Timer um 1 erhöht und der
;Timer neu geladen
pruefSek:
push tmp ;tmp sichern
in tmp, SREG ;SREG sichern
push tmp
inc zaehlerSek ;ZählerSek um 1 erhöhen
ldi tmp, time2 ;Hier wird der Timer vorgeladen
out TCNT2, tmp
pop tmp ;SREG wiederholen
out SREG, tmp
pop tmp ;tmp wiederholen
reti ;wieder dahin, wo du hergekommen bist
;Wenn 1 Sekunde vorbei ist und es noch einen Ton gibt,
;der noch nicht geladen ist dann springe hier hin und
;lade den nächsten Wert von der Datenbank "tonleiter"
ladeton:
clr zaehlerSek ;Zähler wieder auf 0 setzen
lpm ;Daten von tonleiter1: holen
mov tonwert, 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:"
;Wenn alle Töne geladen sind, dann wird das Register "zaehlerTon"
;auf 255 gesetzt
endeTon:
ldi zaehlerTon, 0b11111111 ;ZählerTon auf 255 setzen -> keine weiteren Wert
;mehr von "tonleiter1:" holen
rjmp main ;wieder zurück zu "main:"
;Wird aufgerufen, wenn Timer0 überläuft (Timer für Ton)
;Hier wird geprüft, ob an B.2 HIGH oder LOW anliegt
;und dementsprechend umgesetzt
timerSummer:
push tmp ;tmp sichern
in tmp, SREG ;SREG sichern
push tmp
sbis PINB, Summer ;überspringe, wenn B.2 = 1 ist
rjmp timerSummer1 ;wenn B.2 = 0 ist, dann spring zu "umschalten1:"
cbi PORTB, Summer ;wenn B.2 = 1 ist, dann B.2 auf 0 setzen
rjmp timerSummer2 ;zu "timerSummer2:" springen
timerSummer1:
sbi PORTB, Summer ;wenn B.2 = 0 ist, dann auf 1 setzen
;Hier wird Timer0 mit dem aktuellen Tonwert vorgeladen
timerSummer2:
ldi tmp, 255-tonwert ;Timer mit dem aktuellen Tonwert vorladen
out TCNT0, tmp
rjmp timerSummer4 ;zu "timerSummer4:" springen
timerSummer4:
pop tmp ;SREG wiederholen
out SREG, tmp
pop tmp ;tmp wiederholen
reti
;Das sind die Werte, womit der Timer0 (Tonleiter-Timer) vorgeladen wird
tonleiter1:
.db 28, 16, 14, 0 ;Werte zum Vorladen des Timers für die Töne
;c', a' und c''
Habs auch mit in und out versucht, geht aber auch nicht. Was anderes fällt mir leider nicht ein :(Zitat:
ldi tmp, 255-tonwert ;Timer mit dem aktuellen Tonwert vorladen
Der Code wächst ja ganz schön, hab auch versucht vor jedem Label eine kleine Beschreibung zu schreiben, was darin geschieht. Hoffe, so versteht es auch Florian ;) *g*
Gruß
Thomas
Er meckert, weil tonwert eine Variable ist, die erst zum Zeitlauf geändert wird,Zitat:
ldi tmp, 255-tonwert ;Timer mit dem aktuellen Tonwert vorladen
woher soll der Assembler wissen, was mit tonwert gemeint ist.
Es gab da aber ein Assemblerbefehl fürs Subtrahieren .......
Edit: noch schlimmer, tonwert ist ein register,
Du versuchst von 255 einen register abzuziehen.....