Hi!
Folgendes Problem: Ich brauche auf einem MEGA2560 einen Timerinterrupt
im Sekundentakt.
Denke ein 16bit timer entsprechend konfiguriert ist da die beste Wahl.
Bis jetzt habe ich immer mit MEGA328 gespielt, habs da auch immer
hinbekommen, den Timer richtig zu konfigurieren. Leider klappt es dieses
mal nicht.
Mein Code:
1
//TIMER STARTEN
2
//OC Pins abkoppeln
3
TCCR1A|=((1<<COM1A1));
4
TCCR1A|=((1<<COM1A0));
5
6
//CTC Modus verwenden
7
TCCR1A|=((1<<WGM11));
8
TCCR1A|=((1<<WGM10));
9
10
//PRESCALER 1024
11
TCCR1B|=((1<<CS12));
12
TCCR1B|=((1<<CS11));
13
TCCR1B|=((1<<CS10));
14
15
//CTC Modus verwenden
16
TCCR1B|=((1<<WGM13));
17
TCCR1B|=((1<<WGM12));
18
19
//Interrupte einschalten
20
TIMSK1|=((1<<OCIE1A));
21
22
23
OCR1A=15624;
24
25
sei();
sowie weiter unten im Code:
1
ISR(TIMER1_COMPA_vect)
2
{
3
digitalWrite(RoteLEDPin,HIGH);
4
delay(10);
5
digitalWrite(RoteLEDPin,LOW);
6
Serial.print("interrupt");
7
8
9
}
Erkennt jemand den Fehler? Ich bin das ganze Kapitel im Datenblat
durchgegangen, anscheinend hab ich was übersehen?!
Grüße und danke!
Du veroderst immer in der Form "TCCR1A |=". Setzt du das Teil auch im
Initfall mal auf einen konstanten Wert wie etwa 0 oder greifst du nur
hier auf das Register zu und verlässt dich auf den Reset des
Controllers?
Hi
> TCCR1A |= ((1 << COM1A1));> TCCR1A |= ((1 << COM1A0));
Passt nicht zum Kommentar.
> //CTC Modus verwenden> TCCR1B |= ((1 << WGM12));
bei CTC mit OCR1A als Top muss WGM12 und WGM13 gesetzt sein.
MfG Spess
spess53 schrieb:> bei CTC mit OCR1A als Top muss WGM12 und WGM13 gesetzt sein.
Ich brauch doch Mode 4 und nicht Mode 12? Für Mode 4 nur WGM12.
Felix A. schrieb:> Du veroderst immer in der Form "TCCR1A |=". Setzt du das Teil auch im> Initfall mal auf einen konstanten Wert wie etwa 0 oder greifst du nur> hier auf das Register zu und verlässt dich auf den Reset des> Controllers?
Der Rest sollte automatisch 0 sein, oder?
Thomas E. schrieb:> Mike Litoris schrieb:>> //OC Pins abkoppeln>> TCCR1A |= ((1 << COM1A1));>> TCCR1A |= ((1 << COM1A0));>> Was bezweckst du denn damit?
"These bits control the Output Compare pin (OC0A) behavior. If one or
both of the COM0A1:0 bits are set, the
OC0A output overrides the normal port functionality of the I/O pin it is
connected to."
Das brauch ich nicht, deswegen COMA1 und COMA0 auf 0 für "Normal port
operation, OC0A disconnected."
Danke schonmal!
Frederik H. schrieb:> Es müsste nur TIMSK heißen.
Nein. Es gibt ein Leben nach dem Atmega8.
Mike Litoris schrieb:> Das brauch ich nicht, deswegen COMA1 und COMA0 auf 0 für "Normal port> operation, OC0A disconnected."
Und warum setzt du das dann auf 1?
Hängt da deine LED dran?
mfg.
Normal Port Operation, also kein Zugriff durch den Timer, geht über
COM1A1=0 und COM1A0=0.
OCR1A wird benutzt, wenn nur WGM12=1.
Im TCCR1B den Takt einstellen (das weißt bislang nur du).
Im TIMSK1 nur OCIE1A=1 setzen.
Dann noch den Interruptvektor setzen und sei(); benutzen, um die zu
aktivieren.
Wenn du immerzu TCCR1A |= ... benutzt über viele Zeilen, wird es zum
Einen unübersichtlich und zum Anderen (das hängt davon ab) wurde
vielleicht woanders auf das Register zugegriffen und es steht irgendwo
eine 1, die aber stört.
Durch TCCR1A = (1<<...) | (1<<..) | 1<<.....) würde TCCR1A einen
definierten Wert bekommen.
Kaj schrieb:> Timer 1 wird von dem Arduinozeug intern gebraucht! Nimm 'nen> anderen> Timer, dann sehen wir weiter.
Ist doch gar nicht wahr. Warum wird immer so ein Unsinn erzählt.
Timer 1 wird nur verwendet wenn man mit den analogWrite Befehl auf Pin 9
und/oder 10 verwendet. Macht man das nicht, ist Timer 1 vollkommen frei
verwendbar. Andererseits spricht auch nichts dagegen einen Timer
mehrfach zuverwenden, mit all seinen ISRs. Muß man sich nur vorher mehr
Gedanken machen.
@ Mike: mir fehlt der komplette Code?
Und serial.print hat im ISR Handler auch nichts zu suchen. ISR im ISR.
Macht man nicht. Führt immer zu Problemen.
Hi!
Ich bin das Datenblatt nochmal durchgegangen und habe nun folgende
Konfiguration:
1
//TIMER STARTEN
2
//CTC Modus und 1024 Vorteiler
3
TCCR1B=(1<<WGM12)|(1<<CS10)|(1<<CS12);
4
TIMSK1|=(1<<OCIE1A);
5
6
7
OCR1A=15625;
8
9
sei();
Damit sollte der Interrupt einmal pro Sekunde aufgerufen werden:
16000000/(1024*15624) = 1
Dies ist aber nicht der Fall, der Interrupt wird sehr viel öfter
aufgerufen.
Wo liegt nun der Fehler?
Veit D. schrieb:> Und serial.print hat im ISR Handler auch nichts zu suchen. ISR im ISR.> Macht man nicht. Führt immer zu Problemen.
Weiss ich, ist nur zum testen.
Felix A. schrieb:> Wenn du immerzu TCCR1A |= ... benutzt über viele Zeilen, wird es zum> Einen unübersichtlich und zum Anderen (das hängt davon ab) wurde> vielleicht woanders auf das Register zugegriffen und es steht irgendwo> eine 1, die aber stört.>> Durch TCCR1A = (1<<...) | (1<<..) | 1<<.....) würde TCCR1A einen> definierten Wert bekommen.
Hab versucht das zu beherzigen. Danke!
Grüße!
Veit D. schrieb:> Ist doch gar nicht wahr. Warum wird immer so ein Unsinn erzählt.> Timer 1 wird nur verwendet wenn man mit den analogWrite Befehl
Welcher Timer wird im Arduino benutzt um die Systemuhr zu betreiben?
(Disclaimer: Ich weiss es nicht. Ich frage nur. Dass irgendein Timer
benutzt wird, ist klar. Denn wie soll sonst millis() funktionieren. Die
Frage ist: welcher?)
Karl H. schrieb:> Veit D. schrieb:>>> Ist doch gar nicht wahr. Warum wird immer so ein Unsinn erzählt.>> Timer 1 wird nur verwendet wenn man mit den analogWrite Befehl>> Welcher Timer wird im Arduino benutzt um die Systemuhr zu betreiben?>> (Disclaimer: Ich weiss es nicht. Ich frage nur. Dass irgendein Timer> benutzt wird, ist klar. Denn wie soll sonst millis() funktionieren. Die> Frage ist: welcher?)
Ich verwende die Funktion nicht. soweit ich weiss, wird der Timer dafür
nur verwendet, wenn man die FUnktion mindestens einmal aufruft?
Mike Litoris schrieb:> Ich verwende die Funktion nicht. soweit ich weiss, wird der Timer dafür> nur verwendet, wenn man die FUnktion mindestens einmal aufruft?
Das glaub ich ehrlich gesagt nicht. Das wäre ziemlich unsinnig bei jedem
millis() Aufruf erst mal lang und breit zu prüfen, ob der Timer nicht
schon läuft.
Sorry. Aber Arduino funktioniert nicht nach dem Prinzip "You don't pay
for what you don't use". Wenn das Ardunion System hochfährt krallt es
sich ein paar Dinge und setzt sein Basisystem auf. Möglich, das einzelne
Komponenten erst mit der Benutzung allokiert werden. Aber von
grundlegenden Sachen kann man davon ausgehen, dass die von Anfang an von
der Basissoftware ohne Rücksicht auf Verluste allokiert werden. Und
gerade bei Timern wäre ich da vorsichtig. ALs Arbeitspferde für fast
alles gibt es kaum ein Programm, welches nicht mindestens 1 Timer in
Beschlag hat.
Aber: das lässt sich ja rauskriegen, indem man in einem Testprogramm
welches sonst nichts macht, einfach mal in loop() die
Timerkonfigurationsregister sich ausgeben lässt. Wenn da alles 0 ist,
dann ist der Timer unbenutzt.
Ich konnte leider nicht rausfinden, welchen Timer die millis() Funktion
nutzt.
Ich hab den Interrupt daher mal auf Timer 3 umgezogen. Der wird ja
komplett identisch angesteuert:
1
//TIMER STARTEN
2
TCCR3B=(1<<WGM12)|(1<<CS10)|(1<<CS12);
3
TIMSK3|=(1<<OCIE3A);
4
5
6
OCR3A=15624;
7
8
sei();
und:
1
ISR(TIMER3_COMPA_vect){
2
3
digitalWrite(RoteLEDPin,HIGH);
4
delay(10);
5
digitalWrite(RoteLEDPin,LOW);
6
Serial.println("interrupt");
7
}
selbes Phänomen wie mit Timer 1: Interrupt wird ausgelößt, aber viel zu
schnell...
Veit D. schrieb:> Kaj schrieb:>> Timer 1 wird von dem Arduinozeug intern gebraucht! Nimm 'nen>> anderen>> Timer, dann sehen wir weiter.>> Ist doch gar nicht wahr. Warum wird immer so ein Unsinn erzählt.> Timer 1 wird nur verwendet wenn man mit den analogWrite Befehl auf Pin 9> und/oder 10 verwendet.
hmm, komisch, ich würde dir ja gerne glauben, aber ich habe hier ein
Programm das auf dem Arduino nano328p auf Timer1 läuft, das selbe (OK
das gleiche) Programm eben nicht mit Timer1 auf dem mighty m1284p
Arduino Clone, aber eine kleine Änderung zu Timer3 und es läuft eben.
Ich finde keine Erklärung warum der mighty Arduino Clone nicht mit dem
Programm auf Timer1 läuft.
Joachim B. schrieb:> hmm, komisch, ich würde dir ja gerne glauben, aber ich habe hier ein> Programm das auf dem Arduino nano328p auf Timer1 läuft, das selbe (OK> das gleiche) Programm eben nicht mit Timer1 auf dem mighty m1284p> Arduino Clone, aber eine kleine Änderung zu Timer3 und es läuft eben.>> Ich finde keine Erklärung warum der mighty Arduino Clone nicht mit dem> Programm auf Timer1 läuft.
Nagut, ich habs jetzt mit timer 1, 3 und 5 ausprobiert. Immer das selbe
Ergebnis.
Ich verstehe auch ehrlich gesagt nicht, was noch falsch sein könnte.
SOllte eigentlich alles passen jetzt?
Grüße!
Mike Litoris schrieb:> Ich verstehe auch ehrlich gesagt nicht, was noch falsch sein könnte.> SOllte eigentlich alles passen jetzt?
Sehe ich auch so. Habs 3 mal nachgerechnet. Aber ein Faktor ~60 und das
noch dazu zu schnell ist ungewöhnlich. Da klingelt gar nichts.
Moment. Strohhalm greif.
Hast du schon mal probiert, ob dein µC ständig resetet?
Im setup(): Led ein, delay 1 Sekunde, LED aus, delay 1 Sekunde
Hast du mal ins OCR5A geschrieben und eine Sekunde später den Wert aus
diesem Register gelesen und mal per Uart an ein Terminal gesendet?
Scheint zwar irgendwie sinnlos, aber vielleicht gibt es da irgendwo ne
Macke...
Oder noch einfacher: gibt die Arduino-IDE ein Listfile (.lss oder sowas)
aus, in dem man den Quellcode samt Assemblercode sieht? Da könnte sich
auch ein Blick lohnen.
Mike Litoris schrieb:> Nagut, ich habs jetzt mit timer 1, 3 und 5 ausprobiert. Immer das selbe> Ergebnis.
hast du nachgesehen ob alle Bits in den passenden Register liegen?
vielleicht hilft das ja?
Dieter F. schrieb:> Pack den>> TCCR5A = 0;>> mal noch mit rein, dann funktioniert es auch.
Oha. Funktioniert.
Erklärung? Klingt nämlich ziemlich nach Vodoo?
Grüße - ich brauch jetzt erstma n Bier :D
Hallo,
Timer 0 wird für delay, millis und micros verwendet
Timer 1 wird die Servo Lib verwendet, auf Mega Timer 5
tone() nutzt Timer 2
und dann sind wie schon geschrieben bei Verwendung von analogWrite für
verschiedene Pins verschiedene Timer im Einsatz, aber nur dann eben.
Timer 0 sollte man wirklich in Ruhe lassen. Denn fast jeder gute Code
nutzt millis().
Mir ist noch nicht bekannt das es mit analogWrite und Timer Nutzung
Problem gab.
Mike Litoris schrieb:> Erklärung? Klingt nämlich ziemlich nach Vodoo?
Der Versuch einer Erklärung ...
Aus welchen Gründen auch immer (Arduino-Default ?) ist WGM50 beim Start
gesetzt. Dadurch kommst du in den Mode5 (fast pwm) mit Top-Wert 0x00FF
(passt zu den ca. 61 Hz bei Prescaler 1024).
Bei fast pwm wird das Output Compare Interrupt Flag scheinbar auch
gesetzt ...
"In non-inverting Compare Output mode,
the Output Compare (OCnx) is cleared on the compare match between TC NTn
and OCRnx, and set at BOTTOM.
In inverting Compare Output mode output is set on compare match and
cleared at BOTTOM. "
Müsste man mal debuggen und sich anschauen ... ich hab es halt probiert,
weil ich keiner Initialisierung außer meiner eigenen vertraue :-)
Haut mich :-)
kjel schrieb:>> Kriege sind so negativ>> Nur wenn man so assoziiert.
kommt nicht von mir sondern von meinem Deutschlehrer.
Wer kriegt denn schon? Man bekommt höchstens.
Joachim B. schrieb:> kjel schrieb:>>> Kriege sind so negativ>>>> Nur wenn man so assoziiert.>> kommt nicht von mir sondern von meinem Deutschlehrer.>
Und dann will es keiner gewesen sein.
kjel schrieb:> Und dann will es keiner gewesen sein.
stimmt und deswegen sollte man "Kriege" vermeiden wo es geht zumal es
passenderen Ersatz gibt, hier z.B. "Bekomme"