[erledigt] Hilfe bei Timerprogrammierung erbeten

Hallo allerseits!

Ich möchte ein Rechtecksignal (ca. 2 Hz, 20 % „duty“) erzeugen, das mit 38 kHz moduliert ist.

Aus einem Applikationsbeispiel habe ich Code kopiert, mit dem das funktioniert, wobei allerdings Pin 3 benutzt wird, der schon belegt ist. Bei allen Versuchen, das auf Pin 11 umzuprogrammieren, erhalte ich jedoch nur das unmodulierte Signal. Ich habe noch keine Erfahrungen mit den Timern und verstehe etwas im Atmel-Datenblatt möglicherweise aflsch.

Den mit Pin 3 funktionierenden Code habe ich hier abgelegt. Meine Änderungsversuche betrafen bislang nur die Vorkommen von „COM2B1“, das ich in „COM2A1“ geändert habe und die Zeile, in der das Datenrichtungsregister manipuliert wird (dort mache ich aus „DDD3“ „DDB3“).

Kann mir jemand sagen, wo ich etwas übersehen habe? Ich hänge jetzt seit ein paar Tagen an diesem Problem und hätte es gerne vom Tisch.

Vielen Dank vorweg!

Gregor

Wieso den Overflow Interrupt? Normal macht man das mit PWM. Wenn nicht PWM dann CTC. Wobei man bei PWM gar nicht mal unbedingt einen Interrupt braucht wenn man es geschickt anstellt.

Tip: mit Timer1 in Mode 10 oder Mode 14 kann man den TOP-Wert frei wählen

DDR brauchst du glaube gar nicht. Die COMnA/B Bits überschreiben die normalen Pin Funktionen

Serenifly:
Wieso den Overflow Interrupt? Normal macht man das mit PWM. Wenn nicht PWM dann CTC. Wobei man bei PWM gar keinen Interrupt braucht!

Ich möchte das per Interrupt machen, weil das Signal (für einen IR-Näherungssensor) während der gesamten Laufzeit des Arduinos gleich bleiben und den restlichen Programmablauf nicht stören soll. Außerdem schien mir das Programm in der Application Note für einen Einstieg ins Timer-Thema geeignet zu sein.

Gruß

Gregor

Man kann Timer auch völlig ohne Interrupts verwenden. Bei dir wird der Overflow Interrupt wohl genommen um das Ende der Periode zu erkennen und die Zyklen zu zählen

Der Grund weshalb das nicht geht ist dass das in einem PWM Modus läuft der OCR2A als TOP nimmt! Wenn du COM2A schalten willst dann ist OCR2A aber das Compare Match Register:

//Mode5: PWM phase correct
// with TOP=OCR2A

Am besten du stellst das auf Timer1 in Mode 10 oder 14 um. Dann kann man ICR1 als TOP Register nehmen. Und die Vergleichs-Register sind frei. Mode 10 wäre Phase Correct, wie auch auf Timer2. In Fast PWM muss man den TOP Wert halbieren.

Serenifly:
Der Grund weshalb das nicht geht ist dass das in einem PWM Modus läuft der OCR2A als TOP nimmt! Wenn du COM2A schalten willst dann ist OCR2A aber das Compare Match Register:

Uh. Shit. Um darauf zu kommen, hätte ich noch Wochen gebraucht. Danke!

Serenifly:
Am besten du stellst das auf Timer1 in Mode 10 oder 14 um. Dann kann man ICR1 als TOP Register nehmen. Und die Vergleichs-Register sind frei.

Danke für den Tipp! An einen anderen Timer hatte ich zwar schon gedacht, wollte das aber nicht machen, weil 8 Bit Auflösung ja eigentlich genügen.

Ich werde mich die nächsten Tage mal an einem der 16 Bit-Timer versuchen und nochmal fragen, wenn ich das nicht hinbekomme.

Vielen Dank!

Gregor

Ja. Die 16 Bit brauchst du nicht. Aber das geht genauso wenn man nur 8 Bit davon nutzt. Es gibt auf Timer1 auch zwei Modi in denen TOP fest 0xFF ist!

Timer1 hat aber eben die Input Capture Einheit (um die Länge von externen Ereignisse zu messen). Dadurch steht ein zusätzliches Register zur Verfügung das es auf Timer2 nicht gibt.

Mode 10 mit ICR1 statt OCR2A wäre die direkte Entsprechung zu dem was du auf Timer2 machst