Forum: Mikrocontroller und Digitale Elektronik AVR timer: CTC


von Benedikt K. (benedikt)


Lesenswert?

Ich habe eine Problem mit dem Timer, und zwar möchte ich eine Frequenz 
erzeugen, die verändert werden kann, ohne dass beim Wechseln der 
Frequenz Glitches auftreten. Genau das ist im CTC Modus aber der Fall:
Habe ich am Anfang z.B. den Wert 128 im Compare Register stehen, und 
schreibe danach den Wert 64 rein, dann kann es passieren, dass der 
16bit-Timer bis 65535 zählt, wenn der Zählerstand beim Reinschreiben 
irgendwo zwischen 64 und 128 war, da der Compare dann verpasst wird.
Gibt es dazu ein Workaround ?

von A.K. (Gast)


Lesenswert?

Ja. Zum richtigen Zeitpunkt reinschreiben. Ist die Zeit lang genug, dann 
per Match-Interrupt. Wenn nicht, pollen.

von Willi W. (williwacker)


Lesenswert?

Mach doch das Reinschreiben im Interrupt

Ciao
Willi Wacker

von Benedikt K. (benedikt)


Lesenswert?

Das hatte ich mir schon gedacht: Es gibt also keine ordentliche Lösung. 
Das mit dem Interrupt ist nicht so einfach, da noch andere Interrupts 
eingeschaltet sind. Und die verzögern dann den Compare Interrupt, was 
das Problem also nicht löst.
Pollen ist daher die einzigste Lösung. Also inline Assembler bzw eine 
Assembler Funktion, da der dumme Compiler die Berechnung der Werte für 
die Register zwischen die Timer Abfrage und die Ausgabe der neuen Werte 
packt...

von Johannes M. (johnny-m)


Lesenswert?

Wie schnell läuft Dein Timer denn und wie klein können Deine 
Compare-Werte werden? Wenn alle anderen Interrupt-Handler ausreichend 
kurz sind, dann sollte das bei nicht zu hohen Frequenzen eigentlich 
keine Probleme geben.

von Benedikt K. (benedikt)


Lesenswert?

Die Frequenzen liegen bei 10kHz bis 250kHz. Das bedeutet also 500kHz 
Interruptfrequenz...

von Kupfer Michi (Gast)


Lesenswert?

Ich hab bissher immer den Timer angehalten und OCR und TCNT entsprechend 
neu gesetzt.

Alternative soll sowas laut DB auch über Fast PWM Modus gehen, habs aber 
noch nicht ausprobiert.

von Benedikt K. (benedikt)


Lesenswert?

Stimmt, aber leider brauche ich beide OCR Register, da ich 2 Signale 
erzeugen muss, die gegenphasig sind.

Da muss ich wohl auf einen der tinys wechseln, bei denen OCR1A-C doppelt 
gepuffert sind.

von Fred (Gast)


Lesenswert?

Hi,

wie wäre es, den Timer beim Einstellen des neuen Compare Matches einfach 
zurückzusetzen? Für kleine Compare Matches ergibt sich dann eine bessere 
Ausgabe und der Timer/Counter läuft nicht mehr bis Ultimo durch. Bei 
größeren Werten der Compare Matches haste dann aber wieder Glitch...
Gruß

Fred

von Willi W. (williwacker)


Lesenswert?

Pollen hilft da auch nichts, wenn noch andere Interrupts laufen. Dann 
dauert der Polling-Zyklus auch nicht immer gleich lang.

Wie siehts denn damit aus, in den Interrupts nur Infos zu sammeln und 
die dann im Hauptprogramm zu bearbeiten?

Ciao
Willi Wacker

von ich (Gast)


Lesenswert?

hallo,

"...da ich 2 Signale
erzeugen muss, die gegenphasig sind."

inverter benutzen ?

von Karl H. (kbuchegg)


Lesenswert?

Ein unausgegorener Denkansatz:

Der Problemfall liegt ja nur dann vor, wenn der OCR Wert
kleiner werden soll.
Dann müsste man sich aber ausrechnen können, worauf der Timer
gesetzt werden muss, damit er (samt einem Überlauf) bei
Erreichen des neuen OCR Wertes noch genügeng Zählpulse
für den vorhergehenden OCR Wert tickt.

Alles klar?
(Das da oben klingt grässlich)

Ein Beispiel:

Dein Timer soll der Einfachheit halber bis 16 zählen,
dann erfolgt ein Überlauf.

Der OCR sei 10
Jetzt willst du einen neuen OCR von 7
Der Timer sei momentan bei 8 (müsste also bei einem
OCR von 10 noch 2 mal ticken). D.h. wenn ich den OCR
auf 7 setzte und den Timer auf 5, dann kriege ich noch
2 Ticks bis der CTC das nächste mal zuschlägt.
d.h. im jetzigen Durchagng macht der Timer immer noch
insgesammt 10 Ticks (8 als der OCR noch auf 10 war
und 2 als der OCR schon auf 7 umgestellt war) und
im nächsten Durchgang macht er dann die gewünschten 7 Ticks.

Der OCR sei wieder auf 10 und wieder willst du ihn auf 7
setzen. Aber diesmal sei der Timerwert erst 1.
d.h. der Timer muss noch 9 Ticks machen. d.h. du musst
den Timer auf 7 - 9 + 16 = 14 vorbelegen.


von Karl H. (kbuchegg)


Lesenswert?

Karl heinz Buchegger wrote:
> Ein unausgegorener Denkansatz:

> Der OCR sei wieder auf 10 und wieder willst du ihn auf 7
> setzen. Aber diesmal sei der Timerwert erst 1.
> d.h. der Timer muss noch 9 Ticks machen. d.h. du musst
> den Timer auf 7 - 9 + 16 = 14 vorbelegen.

Das ist Unsinn, wenn der jetzige Timerwert kleiner als
der neue OCR Wert ist, gibt es ja auch kein Problem.

von Benedikt K. (benedikt)


Lesenswert?

Willi Wacker wrote:
> Wie siehts denn damit aus, in den Interrupts nur Infos zu sammeln und
> die dann im Hauptprogramm zu bearbeiten?

Meinst du die anderen Interrupts die noch an sind ?
Wie bereits geschrieben: Der Timer erzeugt 250kHz. Selbst bei 16MHz sind 
das nur max 64 Takte, die schnell weg sind, alleine durch das pushen und 
popen von den Registern in der Interruptroutine.

Selbst die doppelt gepufferten OCR Register bringen nichts: Was 
passiert, wenn der Compare genau zwischen den Änderungen der OCR1A und 
OCR1C Register passiert ? -> Glitch.

Ich denke es gibt nur eine Lösung:

Alle Werte berechnen
cli
warten bis Timer Compare
OCR1A=ocr1a_wert
OCR1C=ocr1c_wert
sei

von Quehl (Gast)


Lesenswert?

im PWM Modus wird die Pufferung des Compareregisters eingeschaltet lt. 
Datenblatt des ATMEGA 32. In den anderen Modi ist er abgeschaltet.

mfg
Quehl

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.