Forum: Mikrocontroller und Digitale Elektronik Woher kommt der Timerüberlauf


von Martin L. (Gast)


Angehängte Dateien:

Lesenswert?

Hi Leute,

ich benutze das angefügte C-Programm um die Zeitdauer einer
Fließkommaberechnung auf einem AVR (Mega16) zu messen.
Das Ganze funktioniert mit einem Timer und geht meiner Ansicht nach
auch schon ganz gut.
Bei Timerprescaler 256 -> zählt er bis 17, bei 64 bis 70, bei 8 bis 556
usw. Das sind demnach 1/(7,372MHz/256)x17 = 600uS.

Nun die Frage: ich habe auch den TimerÜberlauf-Interrupt aktiviert um
zu sehen ob der Timer überläuft. Dieser ist an eine Zählvariable
gekoppelt und zählt somit die Timerüberläufe.

Wenn ich mich recht entsinne dann sind Timer0 und Timer2 beim Mega16
8-Bit Timer die erst bei 255 überlaufen. Die Frage ist nun: Warum wird
dann bei meinem Programm bei jedem Durchgang ein Überlauf produziert?

Wenn ich Timer1 nutze der ja ein 16-Bit Timer ist, wird bei Prescaler
256 & 64 kein Timer-Überlauf-Interrupt ausgelöst und bei Prescaler
kleiner 64 geht es dann wieder los. Der 16-Bit-Timer dürfe selbst bei
Prescaler 1 nicht überlaufen.

Wo liegt der Denkfehler?

Grüße
Martin

von Sonic (Gast)


Lesenswert?

Vielleicht solltest Du vor dem Starten oder Freugeben der
Überlauf-Interruptes das entsprechende Flag rücksetzen ('1'
reischreiben). Wenn das Flag schon ansteht geht der µC gleich in den
Interrupt.

von Marco S. (masterof)


Lesenswert?

die 17 ist das aus dem Timerregister oder aus deiner Überlaufvariable?

von Martin L. (Gast)


Angehängte Dateien:

Lesenswert?

Hi,

da sich anscheinend bislang nur wenige (oder keine Leute) meinen C-Code
angesehen haben hänge ich nochmal die reine c-Datei an.

@Sonic: Welches Flag meinst Du? Ich aktiviere in Zeile 83 den
Timer1-Überlaufinterupt "TIMSK |= ( 1 << TOIE1 );" nach meiner
Berechnung setze ich das Flag wieder zurück "TIMSK &= ~( 1 << TOIE1
);"
Vor allem, warum tritt der Timer1-Überlauf nicht bei den Prescalern 256
& 64 auf?

@masterof: Die 17 ist die Differenz des Timerzählregisters vor der
Berechnung - Timerzählregisters nach der Berechnung.

Code-Auszug:
TIMSK |= ( 1 << TOIE1 );
// bei Timer1-Überlauf wird Interrupt ausgelöst
TCNT1=0;
treg1=TCNT1; // Zählerstand1 sichern
ek = wk-xk;
yk = PI_Regler(ek);
treg2=TCNT1; // Zählerstand2 sichern
TIMSK &= ~( 1 << TOIE1 );
// bei Timer1-Überlauf wird kein Interrupt ausgelöst
tregdiff=treg2-treg1;

Gruz
Martin

von Peter D. (peda)


Lesenswert?

"Vielleicht solltest Du vor dem Starten oder Freugeben der
Überlauf-Interruptes das entsprechende Flag rücksetzen ('1'
reischreiben)."


Jau, so isses !

Du machst davor tonnenweise schnarchlahme UART-Textausgabe und da läuft
halt der Timer über.

Ich würde allerdings einfach nur zur Messung den Timer starten und
stoppen, dann kann auch nichts überlaufen.


Peter

von johnny.m (Gast)


Lesenswert?

> Welches Flag meinst Du? Ich aktiviere in Zeile 83 den
> Timer1-Überlaufinterupt "TIMSK |= ( 1 << TOIE1 );" nach meiner
> Berechnung setze ich das Flag wieder zurück "TIMSK &= ~( 1 << TOIE1
> );"

Das TOIE1 ist kein Flag, sondern das Enable-Bit für den
Timer-Overflow-Interrupt. Das Interrupt-Flag, das sonic meint, heißt
TOV1 und steht im TIFR!

von Sonic (Gast)


Lesenswert?

Ich setze das TOV1 - Flag VOR dem Freigeben des Timer-INTs zurück, dann
bin ich sicher dass es nicht schon ansteht.

von Martin L. (Gast)


Lesenswert?

Danke Leute ich habs gerafft wo mein Denkfehler lag...

Gruz
Martin

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.