Hallo, ich möchte den Timer 2 des Atmega88 via TOSC1 und TOSC2 mittels eines Uhrenquarzes betreiben, um einen sekundengnauen Overflow zu erhalten. Diesen benötige ich um einen einstellbaren Countdown von max. 00:15:00 runter zählen zu lassen. Nur habe ich ein paar Probleme bei der Konfiguration bzw. bei den Ausführungen im Atmel Datenblatt. Mein Ansatz war die Konfiguration zu Beginn der Main, wie folgt vor zunehmen: TIMSK2 &=(~(1<<TOIE2)|(1<<OCIE2A)|(1<<OCIE2B)); ASSR |= (1<<EXCLK); ASSR |= (1<<AS2); TCCR2B |= (1<<CS22)|(1<<CS20); TCNT2 = 0x00; while(ASSR & (1<<TCN2UB)); TIMSK2 &=(~(1<<TOIE2)|(1<<OCIE2A)|(1<<OCIE2B)); TIMSK2 |= (1<<TOIE2); sei(); entsprechend der Angaben im Datenblatt: "Warning: When switching between asynchronous and synchronous clocking of Timer/Counter2, the Timer Registers TCNT2, OCR2x, and TCCR2x might be corrupted. A safe procedure for switching clock source is: a. Disable the Timer/Counter2 interrupts by clearing OCIE2x and TOIE2. b. Select clock source by setting AS2 as appropriate. c. Write new values to TCNT2, OCR2x, and TCCR2x. d. To switch to asynchronous operation: Wait for TCN2xUB, OCR2xUB, and TCR2xUB. e. Clear the Timer/Counter2 Interrupt Flags. f. Enable interrupts, if needed." Doch seit ich dies eingefügt habe, funktionier garnichts mehr in meinem vorher funktionierenden Programm. Auch bei der Compilierung mittels AVR Stuido 4 treten keine Fehler auf. Ich hoffe auf eure Untersützung beim Konfigurieren des Timers. Eine folgende Frage ist, ob es möglich ist nur das TOV2 Bit des TIFR2 abzufragen um damit quasi außerhalb einer ISR den Zähltakt der Uhr zu erzeugen. Sprich ob dies dann ohne eigentliche ISR mögliche wäre, auch das wurde mir aus dem Datenblatt leider nicht deutlich. Für zielführende Tips schon mal vielen Dank im Voraus. Gruß Michel
Gast
#2585234
> ich möchte den Timer 2 des Atmega88 via TOSC1 und TOSC2 mittels eines > Uhrenquarzes betreiben, um einen sekundengnauen Overflow zu erhalten. > ASSR |= (1<<EXCLK); • Bit 6 – EXCLK: Enable External Clock Input When EXCLK is written to one, and asynchronous clock is selected, the external clock input buffer is enabled and an external clock can be input on Timer Oscillator 1 (TOSC1) pin instead of a 32 kHz crystal (= Uhrenquarz!). Writing to EXCLK should be done before asynchronous operation is selected. Note that the crystal Oscillator (= Uhrenquarz!) will only run when this bit is zero.
Gast
#2585237
> Eine folgende Frage ist, ob es möglich ist nur das TOV2 Bit des TIFR2 > abzufragen um damit quasi außerhalb einer ISR den Zähltakt der Uhr zu > erzeugen. Sprich ob dies dann ohne eigentliche ISR mögliche wäre, auch > das wurde mir aus dem Datenblatt leider nicht deutlich. Halte ich für möglich, kann mir aber den Sinn nicht vorstellen.
Hab es jetzt nochmal wie folgt geändert, aber es funktioniert nicht. Könnte mir vlt. jemand helfen und mir meinen Fehler aufzeigen?! ASSR |= (1<<EXCLK); DDRC &= ~(1<<PC5); DDRC |= (1<<PC4); PORTC |= (1<<PC5)|(1<<PC4); DDRD &= ~(1<<PD3); DDRD |= (1<<PD1); PORTD |= (1<<PD3); EICRA |= (1<<ISC11); EIMSK |= (1<<INT1); lcd_init(); lcd_clear(); adc_init(); TIMSK2 &=(~(1<<TOIE2)|(1<<OCIE2A)|(1<<OCIE2B)); ASSR |= (1<<AS2); TCCR2B |= (1<<CS22)|(1<<CS20); TCNT2 = 0x00; TIMSK2 &=(~(1<<TOIE2)|(1<<OCIE2A)|(1<<OCIE2B)); TIMSK2 |= (1<<TOIE2); sei();
rein aus formalen Gründe (also ohne dass ich ins Datenblatt oder nach dem Sinn gefragt habe) kann das hier
1 | |
nicht richtig sein. Ich vermute du wolltest die ~ vor dir Klammer haben. So jeden Falls ist das ein unlogisches Statement. Was soll es bewirken?
1 | |
Was an dem von Krapao geposteten Datenblatt-Zitat war missverständlich?
1 | |
Wegen falscher Klammerung nahezu unwirksam. Glücklicherweise ja aber eh unnötig, oder hast du irgendwann vorher eines der Bits gesetzt? Wo sind die Punkte d und e aus deinem eigenen Datenblatt-Zitat?
Vielen Dank für eure Antworten. Klar das invertieren der Interruptenablebits, muss natürlich anders aussehen. Ist mir gestern allein nicht mehr aufgefallen, aber ich bin auch in keinsterweise sicher in C Programmierung und erst seit ein paar Wochen in Sachen AVRs und Programmierung dabei...sorry. Der Datenblatttext(siehe post Krapao) zu Bit6(EXCLK) des ASSR bleibt für mich dennoch missvertändlich, da zum Einen davon gesprochen wird, dass das Bit logisch 1 sein soll im asynchronen Modus um den Uhrquarz betreiben zu können, zum Anderen der letzte Satz "Note that the crystal Oscillator will only run when this bit is zero." oder ist hiermit der Quarz an XTAL gemeint??? ASSR &= ~(1<<EXCLK) od. ASSR |= (1<<EXCLK); TIMSK2 &= ~((1<<TOIE2)|(1<<OCIE2A)|(1<<OCIE2B)); ASSR |= (1<<AS2); TCCR2B |= (1<<CS22)|(1<<CS20); TCNT2 = 0x00; while(ASSR & (1<<TCN2UB)); //Punkt d TIMSK2 &= ~((1<<TOIE2)|(1<<OCIE2A)|(1<<OCIE2B)); //Punkt e TIMSK2 |= (1<<TOIE2);
Guten Tag, Hier mal ein Code Schnipsel den ich aktuell verwende, der auch funktioniert :
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
Ich habe mir über den Vorteiler die Zeit etwas besser einteilbar gemacht. Vielleicht hilft dir das ja schon weiter, habe mich auch mal mit dem Thema beschäftigt, aber weis leider nicht mehr genau wo das Problem lag. Gruß, Martin
Gast
#2586020
ASSR->EXCLK muß 0 sein und ASSR->AS2 auf 1 ... fertisch.
Danke für eure schnelle Unterstützung, werde ich heute noch ausprobieren und mal sehen, ob es dann funktioniert. Anderfalls "nerv" ich nochmal ... ;)
> while(ASSR & (1<<TCN2UB)); //Punkt d Ich würde mich nicht darauf verlassen, dass es reicht, sich eines der Bits rauszupicken. Ich würde tatsächlich auf alle Bits warten, deren zugehörige Register du beschrieben hast (zumal man das ja auch in nur einer Schleife machen kann). > TIMSK2 &= ~((1<<TOIE2)|(1<<OCIE2A)|(1<<OCIE2B)); //Punkt e Nein, das ist nicht Punkt e. Der sagt "Flags löschen", nicht "Enable-Bits löschen". Und so nebenbei: der Code von Martin macht das auch nicht korrekt.
Hallo Stefan,
auf dein Statement hin muss ich dann doch nochmal fragen.
Hab es jetzt wie folgt umgeschrieben:
ASSR &= ~(1<<EXCLK);
TIMSK2 &= ~(1<<TOIE2);
ASSR |= (1<<AS2);
for(w=0,w<=ww,w++)
{
_delay_ms(10);
}
TCCR2B |= (1<<CS22)|(1<<CS20); // Prescaler 128
TCNT2 = 0x00;
while(ASSR & (1<<TCN2UB));
TIFR2 &= ~(1<<TOV2);
TIMSK2 |= (1<<TOIE2);
1. zu deiner Aussage bezüglich der Wartefunktion:
Ich laden doch nur TCNT2 mit einem Anfangswert und lasse die andere
Register des Zählers doch unangetatet bzw. möchte ich den Timer 2
auch nur zu diesem Zweck und keinem Compare und dergleichem mehr
nutzen.
Stellst du dir das dann wie folgt vor?
while(ASSR &((1<<TCN2UB)|(1<<OCR2AUB)|(OCR2BUB)|
(1<<TCR2AUB)|(1<<TCR2BUB));
2. Okay der Timer hat mehrere Interrupts, sicher muss man dann alle
entsprechenden Flags löschen.
TIFR2&=~((1<<OCF2B)|(1<<OCF2A)|(1<<TOV2))
Gast
#2586353
> 2. Okay der Timer hat mehrere Interrupts, sicher muss man dann alle > entsprechenden Flags löschen. > TIFR2&=~((1<<OCF2B)|(1<<OCF2A)|(1<<TOV2)) Steht im Datenblatt Aber normalerweise löschen sich die Flags von alleine dur ch einen Registerzugriff oder man schreibt eine 1 hinein. ACHTUNG man schreibt eine 1 hinein ZUM LÖSCHEN ! Keine 0 !
Michel Schl. schrieb: > 1. zu deiner Aussage bezüglich der Wartefunktion: > Ich laden doch nur TCNT2 mit einem Anfangswert und lasse die andere > Register des Zählers doch unangetatet Und was ist mit TCCR2B? Michel Schl. schrieb: > Stellst du dir das dann wie folgt vor? > while(ASSR &((1<<TCN2UB)|(1<<OCR2AUB)|(OCR2BUB)| > (1<<TCR2AUB)|(1<<TCR2BUB)); Ja, so in etwa.
1 | |
Michel Schl. schrieb: > 2. Okay der Timer hat mehrere Interrupts, sicher muss man dann alle > entsprechenden Flags löschen. > TIFR2&=~((1<<OCF2B)|(1<<OCF2A)|(1<<TOV2)) Das löscht aber keines der Flags.
1 | |
Oh ja richtig, dass die Flags mit einer 1 gelöscht werden, habe ich mehrfach gelesen. peinlich Vielen Dank für eure schnelle und hilfreiche Unterstützung.
Gast
#2586905
> Der Datenblatttext(siehe post Krapao) zu Bit6(EXCLK) des ASSR bleibt für > mich dennoch missvertändlich, da zum Einen davon gesprochen wird, dass > das Bit logisch 1 sein soll im asynchronen Modus um den Uhrquarz > betreiben zu können, zum Anderen der letzte Satz "Note that the crystal > Oscillator will only run when this bit is zero." oder ist hiermit der > Quarz an XTAL gemeint??? Stimmt doch nicht. Dort ist deutlich entweder von clock oder crystal die Rede und dazwischen steht ein instead D.h. man kann Timer2 entweder 1/ asynchron takten und an TOSC1 eine external clock hängen, also ein externes Taktsignal. Dann muss Bit EXCLK 1 gesetzt werden. oder 2/ asynchron takten und an TOSC1 und TOSC2 einen external crystal (Uhrenquarz) hängen. Dann muss Bit EXCLK 0 gesetzt werden. oder 3/ synchron mit dem Haupttakt takten und TOSC1 und TOSC2 werden nicht benutzt und sind normale IO-Pins.
Antwort schreiben
Bitte melde dich an, um einen Beitrag zu schreiben.