Ich versuche gerade seit geraumer Zeit auf einem ATtiny25 einen Timer (timer1) laufen zu lassen. Dieser soll aus 1/1024-Controllertakt gespeist werden und bei Compare-Match mit OCR1A 'interrupten' und das Zählerregister auf Null zurücksetzen. Letzteres (das auf Null zurücksetzen) funktioniert einfach nicht, der Zähler zählt nach dem Compare-Match einfach munter weiter. Das sagt mir sowohl die AVR-Studio Simulation mit dem 'Simiulator2' als auch die tatsächlich gemessene Periode der Interrupts, die ich am lebenden Objekt mit dem Oszilloskop messe. Weiß da jemand etwas 'drüber? Hab ich vielleicht eine wichtige Nachricht á la 'das geht beim tiny25 nicht' verpasst? Die Initialisierung sieht so aus: (Laut AVR-Studio-Simulation ist das CTC1-Bit gesetzt, das scheint nur ohne Auswirkungen zu bleiben...) ... // Timer1Compare Interrupt initiieren TCCR1 = (1<<CTC1) // Clear Timer/Counter on Compare Match |(0<<PWM1A) // kein PWM-Mode |(0b00<<COM1A0) // kein Durchgriff auf Ausgang |(CLK_1024<< CS10); // Takt durch 1024 dividieren OCR1A = COMPARE_MATCH_VALUE; // Timer1CompareMatch Interrupt freigeben TIMSK = (1<<OCIE1A); ...
Haste mal in der AVRStudio-Hilfe bei den "known issues" geschaut? Ich meine, mich erinnern zu können, dass es mit PWM und CTC im Simulator gewisse Probleme gibt. Abgesehen davon: Wie ist CLK_1024 definiert? Und das Nullenschieben ist überflüssig.
Hi Lt. Datenblatt funktioniert CTC nur mit OCR1C. MfG Spess
>>>Haste mal in der AVRStudio-Hilfe bei den "known issues" geschaut? Ich >>>meine, mich erinnern zu können, dass es mit PWM und CTC im Simulator >>>gewisse Probleme gibt. Hab' ich nicht. Es ist aber so, dass das Verhalten des realen Controllers mit dem der Simulation konsistent ist. >>> Abgesehen davon: Wie ist CLK_1024 definiert? Sorry! So: #define CLK_10240b1011 >>> Und das Nullenschieben ist überflüssig.
Nein, so natürlich nicht! So wie hier unten:
#define CLK_1024 0b1011
(Hatte den Beitrag durch ungeschickte Tastenkombination versehentlich
abgeschickt, bevor er fertig war, sorry nochmal!)
>>> Und das Nullenschieben ist überflüssig.
Ich weiß! Ich möchte aber
1. sehen, was ich fülle und was nicht und
2. wenn ich später an diesen Stellen Einsen haben möchte, muss ich nicht
viel ändern.
>>>Hi >>>Lt. Datenblatt funktioniert CTC nur mit OCR1C. >>>MfG Spess Das ist ja'n Ding! Ich probier das innerhalb der nächsten halben Stunde mal... Vielen Dank für den Tipp!
@spess53: Jetzt, wo Du es sagst, sehe ich selber, dass im Datenblatt unter CTC1 geschrieben steht, dass sich das nur auf OCR1C-Register bezieht. Ich wollte jetzt als nächstes 'einfach' den Code so ändern, dass es dann eben mit diesem Register läuft und schon stehe ich vor dem nächsten Problem: Der eine Teil funktioniert erst ein mal: Die Simulation in AVR-Studio läßt den Zähler so zählen, wie man das erwartet: Er wird nach dem Erreichen des Compare-Wertes im Register OCR1C auf Null zurückgesetzt. Der zweite Teil wäre dann der Interrupt und den scheint es für das ...C-Register nicht zu geben (es gibt kein OCIE1C-Bit und auch keinen entsprechenden Interrupt-Vektor): Wohl Pech gehabt! Dann muss ich das wohl manuell erledigen, das auf Null zurücksetzen des Counters. Danke nochmal für die Hilfe!
Moin sous, Aus dem Datenblatt: In PWM mode (either PWM1A=1 or PWM1B=1) the bit TOV1 is set (one) when compare match occurs between Timer/Counter1 and data value in OCR1C - Output Compare Register 1C. Soll heißen: Der Compare match mit OCR1C ist äquivalent zu einem Overflow. Den Interrupt für Overflow benutzen und Nicht-Pech gehabt. ;) Grüße Olaf
Hallo Olaf, Danke für den Hinweis, das werd' ich gleich probieren. Bei den Atmel-AVRs gilt scheinbar nicht: 'kennt man einen, kennt man alle.' Vielmehr muss man jedesmal wenn man einen neuen vor sich hat, das Datenblatt wieder komplett lesen. Da ich nichts mit pwm machen wollte, habe ich in diesen Regionen auch nicht gelesen... Grüße, Michael
in der Tat, so geht's! init() { TCCR1 = (1<<CTC1) // Clear Timer/Counter on Compare Match |(1<<PWM1A) // PWM-Mode, damit bei CTC ueber OCR1C ein // Overflow-Interrupt ausgeloest wird // ('Warum'-Fragen in diesem Zusammenhang // bitte an Atmel richten...) :) |(CLK_1024<< CS10); // Takt durch 1024 dividieren OCR1C = COMPARE_MATCH_VALUE; // Timer1CompareMatch Interrupt freigeben TIMSK = (1<<TOIE1/*OCIE1A*/); // Freigabe des Timer/Counter- // Overflow-Interrupts ... } ISR(TIM1_OVF_vect /*TIM1_COMPA_vect*/ ) { ... } Danke Olaf!
sous wrote:
> TCCR1 = (1<<CTC1) // Clear Timer/Counter on Compare Match
Wenn ich das Datenblatt richtig verstanden habe, dann ist im PWM-Modus
das CTC1-Bit egal.
Es wird immer nach Erreichen von OCR1C der Timer auf 0 gesetzt.
Den PWM-Modus zu benutzen, ohne die Outputs mit der PWM zu verbinden,
klingt schon etwas seltsam, ist aber nötig für den Overflow-Interrupt.
Peter
>>>Wenn ich das Datenblatt richtig verstanden habe, dann ist im PWM-Modus >>>das CTC1-Bit egal. >>>Es wird immer nach Erreichen von OCR1C der Timer auf 0 gesetzt. Wenn das so wäre, dann wäre das CTC1-Bit in diesem Controller völlig überflüssig. Da es aber existiert, kann ich mir das nicht vorstellen. (Das heißt widerum gar nix, denn ich konnte mir bis heute früh auch all das andere nicht vorstellen, das im Tiny offenbar gilt...) Also den einen Versuch mach ich auch noch, bevor ich endlich weiterarbeite (bin gespannt).
Na suuuper! Das CTC1-Bit scheint im Tiny25 zu nichts gut zu sein (ausser zur Stiftung von Verwirrung vielleicht). Danke für die interessante Info! Es läuft als auch so: // Timer1Compare Interrupt initiieren TCCR1 = /*(0<<CTC1) |*/ // Clear Timer/Counter on Compare Match // Kann man weglassen, hat keine Funktion! (1<<PWM1A) // PWM-Mode, damit bei CTC ueber OCR1C ein // Overflow-Interrupt ausgeloest wird // (Bitte 'Warum'-Fragen an Atmel richten...) |(CLK_1024<< CS10); // Takt durch 1024 dividieren OCR1C = COMPARE_MATCH_VALUE; // Timer1CompareMatch Interrupt freigeben TIMSK = (1<<TOIE1/*OCIE1A*/); ... } ISR(TIM1_OVF_vect/*TIM1_COMPA_vect*/) { ... }
Abschlussbericht: CTC1 ist doch zu etwas gut: Im Nicht-PWM-Modus zählt der Zähler entweder bis 0xff wenn CTC1 nicht gesetzt ist, und bis zum Erreichen des Wertes in OCR1C wenn CTC1 gesetzt ist. Sorry an Atmel und Danke an alle Helfer! ...trotzdem wär's schön, wenn das Peripherieverhalten der verschiedenen Controller etwas konsistenter wäre...
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.