Ups, 'tschuldigung Tekeli! *unschuldig guck*
@ Thomas: Kommst Du weiter?
@ Sebastian:
Thomas hatte erst TOIE0 aktiviert und dann nochmal mit TOIE2 darübergeschrieben und damit wieder TOIE0 deaktiviert! ;o)
@Florian, ich weiß wie schwer es ist jemandem etwas beizubringen,
schön daß Du Dich um den Thomas gekümmert hast, wie gesagt, ich habe es nicht so schön, wie Ihr und muß knechten![]()
Aber in zwei Wochen drehen wir den Spieß um \/ , da hab ich Urlaub!
@Florian,
weißt Du jetzt, wie Du den TIMSK mit 2 Werten belegst?
wo sind wir jetzt stehengeblieben?
Wo war das Problem?
Ich habe zwar alle Beiträge nachgelesen, aber richtig schlau bin ich nicht geworden,
der Thomas hatte ein Problem beide Timer zu benutzen, oder war dort was mit Falschem Timing ???
Ups, 'tschuldigung Tekeli! *unschuldig guck*
@ Thomas: Kommst Du weiter?
@ Sebastian:
Thomas hatte erst TOIE0 aktiviert und dann nochmal mit TOIE2 darübergeschrieben und damit wieder TOIE0 deaktiviert! ;o)
@Tekeli,
bitte schön, ich hoffe, daß es Dir gelingt!
Achso, dann lag ich wohl richtig mit dem "verodern" beider Bits.
Ich hoffe daß es jetzt endgültig klar ist was (1<<PD2) | (1<<PD3) bedeutet.
P.S. Es können auch mehr als 2 Bits sein (1<<PD2) | (1<<PD3) | (1<<PD3) ... usw
Vorteil -> man sieht auf den ersten Blick, was man da für Bits gesetzt hat
Sebastian: In 2 Wochen hast du Urlaub? In 2 Wochen muss ich arbeiten*gg*
Das mit mehr als 2 Bits setzen hab ich dann heut auch kennengelernt, da ich beim Timer 2 3 Bits auf 1 setzen musste, damit ich einen Prescaller von 1024 habe.
Von weiterkommen kann nicht ganz die Rede sein, ich glaub ich änder den Code immer nur um, aber ändern tut sich nichts. Am Anfang hört man kurz ein Knacken von Summer, und dann isses auch schon wieder vorbei. Hier erstmal bis jetzt der Code:
Code:.include "m8def.inc" .equ time0_1 = 256-4 ;Damit wird der Timer2 vorgeladen - für 1KHz .equ time0_2 = 256-1 ;Damit wird der Timer2 vorgeladen - für 4KHz .equ time2 = 256-90 ;Damit wird der Timer0 vorgeladen .equ Summer = PB2 ;Summer an B.2 .def tmp = r16 ;Mein Universallregister .def statusreg = r17 ;Mein Statusregister .def zaehler = r18 ;Mein Zählregister .def statusSummer = r19 ;Mein Summerregister .org 0x000 rjmp reset ;Interruptvektor "reset:" .org OVF2addr rjmp pruefZaehler ;Interruptvektor für Timer2 Überlauf, hier springt ;das Programm hin, wenn der Timer1 überläuft .org OVF0addr ;Interruptvektor für Timer0 Überlauf, hier springt rjmp pruefTon ;das Programm hin, wenn Timer0 überläuft 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 sbi DDRB, Summer ;B.2 als Ausgang sbi PortB, 2 ;B.2 am Anfang aus 1 stellen, damit Ton rauskommt ldi statusSummer, 0b00000000 ;Das erste Bit (Bit0) auf 0 setzen, damit er weiß, ;welchen Ton er abspielen soll. (0 = 1KHz - 1 = 2KHz) ;Timer Register werden belegt, hier Timer 2 ldi tmp, (1<<CS22) | (1<<CS21) | (1<<CS20) ;Prescaler ist 1024 out TCCR2, tmp ;Register TCCR2 ist für den Prescaller zuständig ldi tmp, time2 ;Hier wird der Timer vorgeladen und zwar mit 256-90 out TCNT2, tmp ;Timer Register werden belegt, hier Timer0 ldi tmp, (1<<CS02) | (1<<CS00) ;Prescaler ist 1024 out TCCR0, tmp ;Register TCCR0 ist für den Prescaller zuständig ldi tmp, time0_1 ;Hier wird der Timer vorgeladen und zwar mit 256-4 out TCNT0, tmp ldi tmp, (1<<TOIE0) | (1<<TOIE2);Hier werden Interrupts nach Timer0 und Timer2 eingeschaltet out TIMSK, tmp ;Register TISK ist dafür zuständig sei ;Interrupts zulassen loop: cpi zaehler, 0b00010100 ;Wenn Zählregister != 20 ist brne loop ;dann spring wieder zurück zu "loop:" zeitum0: clr zaehler ;Zählregister auf 0 setzen sbrc statusSummer, 0 ;überspringe, wenn Bit0 = 0 ist rjmp Ton2 Ton1: ldi tmp, time0_1 ;wenn Bit0 = 0 ist, dann mach lad Frequenz 1KHz out TCNT0, tmp rjmp loop ;Wieder zurück zu "loop:" Ton2: ldi tmp, time0_2 ;wenn Bit0 = 1 ist, dann mach lad Frequenz 4KHz out TCNT0, tmp rjmp loop ;Wieder zurück zu "loop:" pruefZaehler: in statusreg, SREG ;SREG sichern inc zaehler ;Zählregister um 1 erhöhen ldi tmp, time2 ;Hier wird der Timer vorgelaen und zwar mit 255-90 out TCNT2, tmp ;Er läuft 90 mal durch, bevor ein Interrupt auftritt out SREG, statusreg ;SREG wiederholen reti ;wieder zurück, wo du hergekommen bist pruefTon: in statusreg, SREG ;SREG sichern sbrs statusSummer, 0 ;überspringe, wenn Bit0 = 1 ist sbr statusSummer, 0 ;wenn Bit0 = 0 ist, dann auf 1 setzen sbrc statusSummer, 0 ;überspringe, wenn Bit0 = 0 ist cbr statusSummer, 0 ;wenn Bit0 = 1 ist, dann auf 0 setzen out SREG, statusreg reti
Hallo,
Ich habe mir kurz Dein Programm angeschaut, dazu ein paar anmerkungen,
bist Du sicher, daß es stimmt?.equ time0_1 = 256-4 ;Damit wird der Timer2 vorgeladen - für 1KHz
.equ time0_2 = 256-1 ;Damit wird der Timer2 vorgeladen - für 4KHz
ich hab selber noch nicht nachgerechnet, aber hmmm.
Den Timer 0 mußt Du in seiner Interruptroutine neu laden, und nicht im Hauptprogramm.
und pruefTon würde ich ganz langsam durchgehen, ob da nicht was falsch ist .
Gruß Sebastian
HI,
die Werte müssten stimmen, das hab ich geprüft.
Hatte das Neuladen von Timer0 vorher auch in der Interruptroutine drinne, änder es ja ständig, langsam blick ich auch nicht mehr durch meinen Code durch.
Ich schau mir dann nochmal pruefTon an, obwohl ich das ja auch mittlerweile schon wieder geändert habe *g*
Gruß
Thomas
[edit]
Um euch auf dem Laufenden zu halten, hier mein aktuelle Code:
Hab nun für Timer0 auch einen Zähler eingebaut, denk mal, den brauch ich. in pruefTon wird der Timer immer wieder neugeladen. Tjo, und den Rest find ich eigentlich logisch. Ich denk mal, der Fehler muss in pruefTon liegen, da er ja nur ein kurzes Knacken von sich gibt.Code:.include "m8def.inc" .equ time0_1 = 256-4 ;Damit wird der Timer2 vorgeladen - für 1KHz .equ time0_2 = 256-1 ;Damit wird der Timer2 vorgeladen - für 4KHz .equ time2 = 256-90 ;Damit wird der Timer0 vorgeladen .equ Summer = PB2 ;Summer an B.2 .def tmp = r16 ;Mein Universallregister .def statusreg = r17 ;Mein Statusregister .def zaehlerSek = r18 ;Mein Zählregister für die halbe Sekunde .def statusSummer = r19 ;Mein Summerregister .def zaehlerTon = r20 ;Mein Zählregister für den Ton .org 0x000 rjmp reset ;Interruptvektor "reset:" .org OVF2addr rjmp pruefZaehler ;Interruptvektor für Timer2 Überlauf, hier springt ;das Programm hin, wenn der Timer1 überläuft .org OVF0addr ;Interruptvektor für Timer0 Überlauf, hier springt rjmp pruefTon ;das Programm hin, wenn Timer0 überläuft 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 sbi DDRB, Summer ;B.2 als Ausgang sbi PortB, 2 ;B.2 am Anfang aus 1 stellen, damit Ton rauskommt ldi statusSummer, 0b00000000 ;Das erste Bit (Bit0) auf 0 setzen, damit er weiß, ;welchen Ton er abspielen soll. (0 = 1KHz - 1 = 2KHz) ;Timer Register werden belegt, hier Timer 2 ldi tmp, (1<<CS22) | (1<<CS21) | (1<<CS20) ;Prescaler ist 1024 out TCCR2, tmp ;Register TCCR2 ist für den Prescaller zuständig ldi tmp, time2 ;Hier wird der Timer vorgeladen und zwar mit 256-90 out TCNT2, tmp ;Timer Register werden belegt, hier Timer0 ldi tmp, (1<<CS02) | (1<<CS00) ;Prescaler ist 1024 out TCCR0, tmp ;Register TCCR0 ist für den Prescaller zuständig ldi tmp, time0_1 ;Hier wird der Timer vorgeladen und zwar mit 256-4 out TCNT0, tmp ldi tmp, (1<<TOIE0) | (1<<TOIE2);Hier werden Interrupts nach Timer0 und Timer2 eingeschaltet out TIMSK, tmp ;Register TISK ist dafür zuständig sei ;Interrupts zulassen loop: cpi zaehlerTon, 0b00000001 ;Wenn Zählregister für Ton = 1 ist breq pruefFrequenz ;dann spring zu "pruefTon:" cpi zaehlerSek, 0b00010100 ;Wenn Zählregister != 20 ist brne loop ;dann spring wieder zurück zu "loop:" zeitum0: clr zaehlerSek ;Zählregister auf 0 setzen rjmp loop pruefFrequenz: sbrs statusSummer, 0 ;überspringe, wenn Bit0 = 1 ist sbr statusSummer, 0 ;wenn Bit0 = 0 ist, dann auf 1 setzen sbrc statusSummer, 0 ;überspringen, wenn Bit0 = 0 ist cbr statusSummer, 0 ;wenn Bit0 = 1 ist, dann auf 0 setzen rjmp loop pruefZaehler: in statusreg, SREG ;SREG sichern inc zaehlerSek ;Zählregister um 1 erhöhen ldi tmp, time2 ;Hier wird der Timer vorgelaen und zwar mit 255-90 out TCNT2, tmp ;Er läuft 90 mal durch, bevor ein Interrupt auftritt out SREG, statusreg ;SREG wiederholen reti ;wieder zurück, wo du hergekommen bist pruefTon: in statusreg, SREG ;SREG sichern inc zaehlerTon ;Zählregister um 1 erhöhen sbrs statusSummer, 0 ;überspringe, wenn Bit0 = 1 ist ldi tmp, time0_2 ;wenn Bit0 = 0 ist, dann Frequenz 2 (4KHz) laden sbrc statusSummer, 0 ;überspring, wenn Bit0 = 0 ist ldi tmp, time0_1 ;wenn Bit0 = 1 ist, dann Frequenz 1 (1KHz) laden out TCNT0, tmp out SREG, statusreg ;SREG wiederholen reti ;wieder zurück, wo du hergekommen bist
Thomas,
so werden wir nicht weiterkommen.
Du mußt Dir erstmal ein Zettel nehmen, und darauf fängt Deine Arbeit an,
mann kann sich dort den zeitlichen Ablauf schön malen, wie das aussehen sollte,
dann schreib Dir nur einen Interrupt für den Ton.
darin dürfte nach meinem Kopf nur eins stehen, und zwar das neuladen des Timers!
Prufe aber darin deinen Status Summer, und jenachdem welchen Wert der hat lädst Du anderen Wert ein.
Und im anderem Interrupt -> dem für die Sekunde den inc rein, und im Hauptprogramm
nur prüfen ob sekunde um ist und jenachdem den Status Summer umschalten, so müßte es gehen.
Außerdem stell ich mir die Frage, an welcher stelle Du den Pin umschaltest, wo Dein Summer dranhängt?
hier setzt Du ihn auf high,und an welcher stelle geht er auf LOW?sbi PortB, 2
irgendwie muß Du ihn in 4khz oder 1kHz Takt umschalten,
oder habe ich da was auf den Augen ?????
Ich setz ihn gar nicht auf LOW. Er soll von Anfang an den Ton ausgeben, das passiert bei mir, wenn das Bit 1 ist.
Ich mal mir grad nen Schema, setzte es grad noch in Paint um und poste es dann hier.
So, hier ist mal mein Schema, so müsste es doch stimme, oder?
Lesezeichen