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.
>>>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
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...