Hallo, ich wollte einen Timer so konfigurieren, dass er einen passiven Piezo-Buzzer ansteuert. Dazu sollten die Ausgangs-Pins im Idealfall folgende Werte annehmen: Bei TCNT=0: Pin0=LOW Pin1=HIGH Bei TCNT=49: Pin0=HIGH Pin1=LOW Bei TCNT=99: TCNT=0 setzen Das Problem ist hier bei Timer0, dass er, wieso auch immer, OCRA für den Top-Wert nimmt. Gleichzeitig nimmt er aber für Pin0 auch OCRA für den Compare-Wert, wo er umschalten soll. Ich habe also gar keine Chance, den Timer so wie oben gewünscht zu konfigurieren. Habe ich jetzt einfach ein Brett vor dem Kopf, oder ist der Timer wirklich braindead designed? Der Timer1 ist wesentlich aufgebohrter und dort kann ich den Register ICR nehmen, um die wrap-around Grenze des Timers festzulegen. Aber leider ist der Timer1 schon belegt und ich muss mit Timer0 für meinen kleinen Buzzer auskommen. Wer kann helfen? PS: Ich verwende den t24a, aber sehr viele tinys nehmen den gleichen Timer.
Beitrag #6381095 wurde von einem Moderator gelöscht.
Das erscheint mir ein wenig umständlich. Du willst doch nur, dass alle 50 Timer-Takte die Ausgänge OC0A und OC0B toggeln. Dazu sollte es ausreichen, den Timer im CTC-Mode zu betreiben, sowohl OCR0A als auch OCR0B auf 49 zu setzen und vorm Start des Timers OC0B auf HIGH zu intialisieren.
1 | PORTA |= (1 << PA7); // set OC0B |
2 | OCR0A = 49; |
3 | OCR0B = 49; |
4 | TCCR0A = 0b01010010; // CTC mode, toggle OC0A |
5 | TCCR0B = 0b00000XXX; // and OC0B on compare match |
Ich habe es nicht ausprobiert, aber nach meinem Verständnis sollte das funktionieren. Gruß, Bernd
Hans schrieb: > Ich habe also gar keine Chance, den > Timer so wie oben gewünscht zu konfigurieren. Habe ich jetzt einfach ein > Brett vor dem Kopf, oder ist der Timer wirklich braindead designed? Für solche Zwecke wurde der Timer/Counter type D entwickelt: "Generating complementary driving signals"
Hans schrieb: > PS: Ich verwende den t24a, aber sehr viele tinys nehmen den gleichen > Timer. Nicht nur viele Tinys, auch die meisten Megas. Bei den Tinys gibt es aber auch welche, die invertierte Timerausgänge in Hardware zur Verfügung stellen, da braucht man dann nur einen Kanal des Timers, z.B. 25/45/85 oder auch 26 oder auch 261/461/861. Und es gibt Tinys mit mehr als einem 16Bit-Timer (incl. ICR-Register), z.B.: 441/841 Und, wie schon von Georg M. angemerkt, gibt es die neueren Tinys mit TypD-Timern. Also mehr als reichliche Auswahl...
Hans schrieb: > Das Problem ist hier bei Timer0, dass er, wieso auch immer, OCRA für den > Top-Wert nimmt. Gleichzeitig nimmt er aber für Pin0 auch OCRA für den > Compare-Wert, wo er umschalten soll. Es gibt ja noch OCRB. Damit geht PWM auch in Verbindung mit einer variablen Zählerobergrenze. Dann wird das Signal eben auf einem anderen Pin ausgegeben. Da du aber kein anderes Tastverhältnis als 0,5 benötigst, brauchst du nicht einmal PWM, sondern kannst wahlweise OC0A oder OC0B (oder auch beide) bei jedem Zählerdurchlauf toggeln lassen (s. Beitrag von Bernd). Dabei muss die Timer-Periode die Hälfte der gewünschten Periodendauer am Ausgang betragen. Wenn das für dich – aus welchen Gründen auch immer – auch keine Option ist, hast du eben den falschen µC-Typ ausgewählt. Es liegt in der Natur der Sache, dass nicht jeder alles können kann. Stefan ⛄ F. schrieb: > Man kann die Ausgänge auch in einer ISR toggeln. Das wird halt etwas unrund. Insbesondere dann, wenn noch weitere Interrupts im Spiel sind, wird man das vermutlich hören.
Wenn nur vereinzelt und kurz gepiept wird, dann geht es auch ohne Timer/Counter, nur mit delay.
Yalu X. schrieb: > Stefan ⛄ F. schrieb: >> Man kann die Ausgänge auch in einer ISR toggeln. > > Das wird halt etwas unrund. Insbesondere dann, wenn noch weitere > Interrupts im Spiel sind, wird man das vermutlich hören. Genau so eine Situation hatte ich bei meinem Platinenbelichter. Einerseits den Interrupt für die Abfrage des Drehgebers, andererseits der Interrupt für das Pulsen des Buzzers. Ich habe das einfach so gelöst, daß ich an den Anfang der Drehgeber-ISR ein
1 | sei() |
gesetzt habe. Ohne das hatte ich in der Tat ein komisches Schnarren im Buzzer-Signal. Mit ist keine Anomalie mehr hörbar, obwohl die Buzzer-ISR hin und wieder verzögert werden wird. µC ist ein AT90S2313 (ja, der ganz alte). Da hatte ich nur noch Timer0 ohne CTC-Modus zu Verfügung und lade in der ISR auch noch den Timer neu:
1 | /* toggle buzzer pins */
|
2 | ISR(TIMER0_OVF0_vect) |
3 | {
|
4 | TCNT0 = 130; |
5 | PORTD ^= (_BV(buzzer_pin_a) | _BV(buzzer_pin_b)); |
6 | }
|
Danke Bernd. Hat so funktioniert. Ich dachte, nur im PWM gibt der Controller Signale an den Pins aus. So kann man sich irren.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.