Hi,
ich bekomme bei meinem ATmega1284P den Timer2 einfach nicht gestartet.
Der Code, mit dem ich versuche den Timer zu aktivieren:
1
ASSR|=(1<<EXCLK);
2
ASSR|=(1<<AS2);
3
TCNT2=0;
4
//enable in CTC mode, w/o prescaler
5
TCCR2A=(1<<WGM21);
6
TCCR2B=(1<<CS20);
7
OCR2A=127;
8
//clear timer / counter interrupt flags
9
TIFR2=(1<<OCF2B)|(1<<OCF2A)|(1<<TOV2);
10
TIMSK2=(1<<OCIE2A);
Bei der Reihenfolge habe ich mich an die im Datenblatt beschriebene
"sichere Prozedur" um in den asynchronen Modus zu wechseln gehalten
(Kapitel 17.9).
"Wait for TCN2UB, OCR2xUB, and TCR2xUB" habe ich dabei wieder
auskommentiert, weil das ansonsten eine Endlosschleife ist.
Beim Debuggen mit JTAG habe ich bemerkt, dass den µC gar nicht
interessiert, ob ich irgendwelche Flags in den Registern gesetzt habe.
Direkt nach Ausführung der letzten geposteten Zeile sind die Register
TIFR2, GTCCR, TIMSK2, TCCR2A, TCCR2B, TCNT2, OCR2A, OCR2B und ASSR alle
mit 0x00 belegt. Auch beim schrittweisen debuggen ändern sich die Werte
nicht.
Das einzige Register, welches sich beschreiben ließ war GTCCR. Darin
hatte ich testweise die Flags TSM und PSRASY gesetzt, bevor ich die
anderen beschreiben wollte und nach dem "beschreiben" das TSM Flag
gecleared. Beschreiben ließen sich die Register trotzdem nicht.
Am TOSC1 Pin liegt ein Rechtecksignal mit 1Hz an (von einer RTC), das
Bit vom Inputpin togglet auch so wie es soll.
Die ISR für den TIMER2_COMPA_vect ist auch definiert.
Woran kann es liegen, dass sich die Register nicht beschreiben lassen?
Alle anderen Timer des ATmega (Timer0, Timer1 und Timer3) funktionieren
wie gewohnt.
Vielen Dank und Grüße
Christian
Der kompilierte ASM Code:
Christian Rudolph schrieb:> Beim Debuggen mit JTAG habe ich bemerkt, dass den µC gar nicht> interessiert, ob ich irgendwelche Flags in den Registern gesetzt habe.> Direkt nach Ausführung der letzten geposteten Zeile sind die Register> TIFR2, GTCCR, TIMSK2, TCCR2A, TCCR2B, TCNT2, OCR2A, OCR2B und ASSR alle> mit 0x00 belegt. Auch beim schrittweisen debuggen ändern sich die Werte> nicht.> Das einzige Register, welches sich beschreiben ließ war GTCCR. Darin> hatte ich testweise die Flags TSM und PSRASY gesetzt, bevor ich die> anderen beschreiben wollte und nach dem "beschreiben" das TSM Flag> gecleared. Beschreiben ließen sich die Register trotzdem nicht.>> Am TOSC1 Pin liegt ein Rechtecksignal mit 1Hz an (von einer RTC), das> Bit vom Inputpin togglet auch so wie es soll.
Die Register des Timers werden mit dem asynchronen Takt getriggert. Das
sind bei dir 1Hz. Das kannst du vergessen. Das kann schon mit 32KHz
Probleme geben.
http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial/Die_Timer_und_Z%C3%A4hler_des_AVR#Wenn_er_die_Minute_in_20s_schafft
mfg.
Nichtsdestotrotz sollten sich die Register anfangs doch schreiben
lassen, oder nicht? Denn bevor ich EXTCLK und AS2 setze, bekommt der
Timer ja die CPUclk (in meinem Fall 4MHz).
Und wenn ich den Artikel richtig verstanden hat, dann wirkt sich diese
Problematik auf die Ausführung der ISR aus. Der Timer startet bei mir
aber gar nicht - auch nicht im synchronen Modus.
Alternativ kann ich mit dem PCINT2 einen softwaretimer bauen, was
natürlich nicht so schön wäre.
Christian Rudolph schrieb:> Nichtsdestotrotz sollten sich die Register anfangs doch schreiben> lassen, oder nicht? Denn bevor ich EXTCLK und AS2 setze, bekommt der> Timer ja die CPUclk (in meinem Fall 4MHz).>> Und wenn ich den Artikel richtig verstanden hat, dann wirkt sich diese> Problematik auf die Ausführung der ISR aus. Der Timer startet bei mir> aber gar nicht - auch nicht im synchronen Modus.>> Alternativ kann ich mit dem PCINT2 einen softwaretimer bauen, was> natürlich nicht so schön wäre.
Der startet irgendwann. Nachdem das AS2-Bit gesetzt wurde, ist der
Async-Takt der Takt für alle Register des Timers.
Dafür ist das da:
>"Wait for TCN2UB, OCR2xUB, and TCR2xUB" habe ich dabei wieder>auskommentiert, weil das ansonsten eine Endlosschleife ist.
Damit wird gewartet bis die Register geschrieben sind. Aber mit 1Hz wird
der Timer nicht nur zur Schlaftablette sondern zu einer zugedröhnten
Schlaftablette.
Schalte den TOSC1-Pin als normalen Porteingang und benutze den
Pinchange-Interrupt zum Sekunden zählen.
Die Async-Mimik ist dazu gedacht, daß sie mit 32KHz betrieben wird.
mfg.
Thomas Eckmann schrieb:> Schalte den TOSC1-Pin als normalen Porteingang und benutze den> Pinchange-Interrupt zum Sekunden zählen.
Das eigentliche Ziel ist es, den µC schlafen zu lassen und dann nach
mehreren Sekunden wieder aufzuwecken. Das geht natürlich auch mit einem
Prescaler von 1024 und OCRA von einem Vielfachen von 32.
> Die Async-Mimik ist dazu gedacht, daß sie mit 32KHz betrieben wird.
Ich habe die RTC umgestellt, sodass sie jetzt ein 32kHz Rechtecksignal
ausgibt. Auch nach mehreren Minuten sind die Register nicht gesetzt.
Was mich wie gehabt wundert, ist dass trotz ASSR auf 0x00 (also Timer2
im synchronen Modus, kein externer Takt) die Register nicht beschrieben
werden.
Das mit dem Warten auf die TCN2UB etc. Flags ist im Datenblatt etwas
missverständlich ausgedrückt. Es liest sich so, als ob man darauf warten
soll, dass die Flags gesetzt sind. Das macht aber eigentlich keinen Sinn
(das OCR2B Register versuche ich z.B. gar nicht zu setzen, daher kann
das OCR2BUB Flag niemals high werden) und deshalb hatte ich eine
Endlosschleife.
Wenn ich sinnigerweise darauf warte, dass alle Flags low sind, dann ist
das sofort der Fall, weil die Flags nicht gesetzt werden.
Christian Rudolph schrieb:> Das mit dem Warten auf die TCN2UB etc. Flags ist im Datenblatt etwas> missverständlich ausgedrückt. Es liest sich so, als ob man darauf warten> soll, dass die Flags gesetzt sind. Das macht aber eigentlich keinen Sinn> (das OCR2B Register versuche ich z.B. gar nicht zu setzen, daher kann> das OCR2BUB Flag niemals high werden) und deshalb hatte ich eine> Endlosschleife.> Wenn ich sinnigerweise darauf warte, dass alle Flags low sind, dann ist> das sofort der Fall, weil die Flags nicht gesetzt werden.
Die Flags müssen OR und nicht AND verknüpft werden.
Wenn du den Async-Mode einschaltest, danach die Timerregister setzt und
dann sofort mit dem Debugger zuschlägst, sind die Register noch leer.
Hast du mal probiert, die Timerregister vorher zu setzen und dann auf
Async zu schalten?
mfg.
Thomas Eckmann schrieb:> Wenn du den Async-Mode einschaltest, danach die Timerregister setzt und> dann sofort mit dem Debugger zuschlägst, sind die Register noch leer.> Hast du mal probiert, die Timerregister vorher zu setzen und dann auf> Async zu schalten?
Ich bin den Code schrittweise durchgegangen, habe den Code in einem
Rutsch ausführen lassen und danach einen Breakpoint gesetzt, aber beides
hat nicht funktioniert.
der alte Hanns schrieb:> bei mir läuft (in Assembler und ohne Interrupt)
Das entspricht in C wohl
Ich habe den kompilierten ASM Code analysiert, bis zur update-loop ist
der Code identisch (der Compiler hat statt ein Register in dem eine 0
stand wiederverwendet, also ist es eine ldi Anweisung weniger).
Die update-loop prüft doch, ob eines der drei Flags TCN2UB, OCR2AUB oder
TCR2AUB gesetzt ist, oder?
Für meinen Code habe ich folgendes bekommen:
Edit: 0xB6 ist die Adresse, an der das ASSR Register liegt.
Edit2: 0x1A ist die Bitmaske für TCN2UB, OCR2AUB und TCR2AUB. Edit-Ende
Mich macht dabei stutzig, dass er zu 0x1d2 springt. Ändert sich das
Zeroflag denn überhaupt noch?
c-hater schrieb:> Falsche Part-Definition included?
Definitiv nicht. Es funktionieren die anderen Timer, TWI ist auch
erfolgreich in Benutzung und die angesprochenen Ausgänge sind auch
korrekt. Selbst den Interrupt auf dem TOSC1 Pin kann ich auslösen
lassen.
So, des Fehlers Ursache ist gefunden...
Ich schäme mich schon fast das hier zu schreiben. Als ich die
Programmierung vor fast einem Jahr begonnen habe, habe ich alle zu dem
Zeitpunkt nicht benötigten Module des µC deaktiviert:
1
voidinitialize_uc()
2
{
3
//disable Timer/Counter 0, synchronous Timer/Counter 2, SPI and ADC
Deshalb ließen sich die Register nicht schreiben!
Dass es an dem Programmcode liegen muss habe ich bemerkt, als ich den µC
nochmal nur mit dem Timercode geflasht habe und es dann funktionierte.
Danke an alle für die Hilfe!
Grüße
Christian