Woher kommt der Timerüberlauf

Gast #400438
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
Angehängte Dateien:
Gast #400439
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.
Gast #400441
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
Angehängte Dateien:
#400442
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
Gast #400443
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!

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren