Hallo Forum
versuche gerade einen 16 Bit Timer mit dem Atmega 1284p zu schreiben.
Leider will die LED nicht leuchten.
Habe dazu das Stück Code im Programm:
1
#define F_CPU 16000000UL // Angabe der Quarzfrequenz, wichtig für die Zeit
Wenn ich das richtig verstanden habe, arbeitet mein Prz mit 16MHz, teile
es mit 64 runter und setze den Wert auf 12499. Damit erreiche ich einen
Wert von 20 Hz. Mit tcount will ich einen anderen Wert zählen und
auswerten.
Doch leider klappt es nicht. Kann ich auch 1 ms erreichen? Wie muss sich
OCR1A verändern um eine höhere Frequen zu erreichen z.B. 124 für 2kHz?
LG Peter
Peter schrieb:> Habe es so geändert
Und? Besser jetzt?
> TCCR1B |= (1<<WGM12)|(1<<CS11)|(1<<CS10); // Einstellung CTC Modus,
Warum eigentlich "|="? Du willst doch eh alles in diesem Register
schreiben, also einfach "=".
> OCR1A=12499; // 50ms = 20Hz
Da du F_CPU obendrüber definierst, warum lässt du das nicht den Compiler
ausrechnen?
1
OCR1A=(F_CPU/64/* prescaler *//20/* Hz */)-1;
Aber meiner Meinung nach ist das "- 1" dort nicht korrekt.
Peter schrieb:> Leider will die LED nicht leuchten.
Leuchtet sie denn (dauerhaft), wenn du den Port initial (vor dem Start
des Timers) einmal toggelst?
Sie leuchtet dauerhaft. 20 Hz noch zu schnell?
Jörg W. schrieb:> Da du F_CPU obendrüber definierst, warum lässt du das nicht den Compiler> ausrechnen?> OCR1A = (F_CPU / 64 /* prescaler */ / 20 /* Hz */) - 1;> Aber meiner Meinung nach ist das "- 1" dort nicht korrekt.
Ist die Zeile dann so?
OCR1A = (F_CPU/64/20-1);
Sorry, der Sinn von 20-1 ist mir nicht klar.
Jörg W. schrieb:> Aber meiner Meinung nach ist das "- 1" dort nicht korrekt.
Um das +1 oder -1 braucht man sich hier nicht streiten wenn
sonst nichts funktioniert.
Peter schrieb:> Sie leuchtet dauerhaft. 20 Hz noch zu schnell?
Nein, es sind ja auch 10 Hz. Die Interruptrate ist 20 Hz, aber mit
jedem Interrupt toggelst du die LED, sodass sie nur mit 10 Hz
flimmert. Das sollte man schon gut als Flimmern wahrnehmen.
Wenn das immer noch nicht geht, müsstest du wohl mal mit einem
vollständigen, compilierbaren Beispiel aufwarten.
>> Aber meiner Meinung nach ist das "- 1" dort nicht korrekt.>> Ist die Zeile dann so?>> OCR1A = (F_CPU/64/20-1);
Nein, gar kein "-1". Der Timer zählt von 0 bis OCR-1. Wenn er auf OCR
weiterschaltet, wird er sofort auf 0 rückgesetzt, damit taucht der Wert
OCR in TCNT nie sichtbar auf.
STM Apprentice schrieb im Beitrag #5689247:
> Um das +1 oder -1 braucht man sich hier nicht streiten wenn> sonst nichts funktioniert.
Das ist richtig. Ein Fehler ist es trotzdem, daher war es mir die
Anmerkung wert.
Peter schrieb:> Ist die Zeile dann so?>> OCR1A = (F_CPU/64/20-1);
Jepp. Klammern sind hier überflüssig, also:
1
OCR1A=F_CPU/64/20-1;
Nimm einfach einen Taschenrechner:
1
16000000 / 64 / 20 - 1 = 12499
> Sorry, der Sinn von 20-1 ist mir nicht klar.
Ist nicht 20 minus 1, sondern das Resultat der Division minus 1 wegen
Punkt-vor-Strich-Rechnung.
Schaue Dir die Formel mal an in obigem Auszug aus dem Datenblatt und
löse die Gleichung nach OCRnA auf. Dann weisst Du auch, wo die -1
herkommt. Allerdings sehe ich in der Formel noch einen Faktor 2, den ich
bei Dir vermisse.
Klaus schrieb:> Entsprechenden Pin auf Ausgang gesetzt?
Da die LED immer an ist, sollte das wohl der Fall sein …
Wie geschrieben: ohne vollständigen, compilierbaren Beispielcode kommen
wir nicht weiter.
Hi
>In der Timer-Initialisierung fehlt noch:> TCCR1C = (1<<FOC1A); /* Force Output Compare A */
Habe ich bei keiner keiner meiner vielen CTC-Anwendung je benutzt. Was
soll das machen (was FOCnx bewirkt ist mir bekannt)?
MfG Spess
Frank M. schrieb:> Schaue Dir die Formel mal an in obigem Auszug aus dem Datenblatt und> löse die Gleichung nach OCRnA auf. Dann weisst Du auch, wo die -1> herkommt.
Gut, das korrigiert meine oben geäußerte Meinung dann, die -1 muss
bleiben.
> Allerdings sehe ich in der Formel noch einen Faktor 2, den ich> bei Dir vermisse.
Das ist die Toggle-Frequenz, die sich ergibt. Die LED blinkt halt mit 10
Hz, wenn die ISR mit 20 Hz getriggert wird.
Im Falle der obigen Formel ergibt sie sich durch das Setzen des "Toggle
on compare match"-Bits, im Fall des TEs erfolgt das Toggeln explizit
durch die XOR-Anweisung auf dem Portpin.
Jörg W. schrieb:> Das ist die Toggle-Frequenz, die sich ergibt. Die LED blinkt halt mit 10> Hz, wenn die ISR mit 20 Hz getriggert wird.
Jepp. Das sollte man auch mit bloßem Auge erkennen können.
Wie sieht denn das gesamte Programm aus? Bzw. wie ist der Ausgabe PIN
initialisiert.
Laut Datenblatt findet sich zu Port C:
Port C is an 8-bit bi-directional I/O port with internal pull-up
resistors (selected for each bit). The Port C output buffers
have symmetrical drive characteristics with both high sink and source
capability. As inputs, Port C pins that are
externally pulled low will source current if the pull-up resistors are
activated. The Port C pins are tri-stated when a
reset condition becomes active, even if the clock is not running.
Demnach sollten die Pins von PORTC nach dem Einschalten im Tristate
Zustand sein, d.h. wohl als INPUT und ohne Pullup Widerstand.