Forum: Mikrocontroller und Digitale Elektronik ATtiny25, TimerCounter1, CTC-Mode: Bug?


von sous (Gast)


Lesenswert?

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

von Johannes M. (johnny-m)


Lesenswert?

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.

von spess53 (Gast)


Lesenswert?

Hi

Lt. Datenblatt funktioniert CTC nur mit OCR1C.

MfG Spess

von sous (Gast)


Lesenswert?

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

von sous (Gast)


Lesenswert?

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.

von sous (Gast)


Lesenswert?

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

von sous (Gast)


Lesenswert?

@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!

von Olaf (Gast)


Lesenswert?

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

von sous (Gast)


Lesenswert?

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

von sous (Gast)


Lesenswert?

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!

von Peter D. (peda)


Lesenswert?

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

von sous (Gast)


Lesenswert?

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

von sous (Gast)


Lesenswert?

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*/)
{
...
}

von sous (Gast)


Lesenswert?

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
Noch kein Account? Hier anmelden.