Forum: Mikrocontroller und Digitale Elektronik Zeitmessung GCC


von Matthias (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,

ich versuche gerade die Zeit zwischen 2 Impulsen zu messen. Leider
messe ich fast Zufällige Werte, weshalb wohl irgendwo ein größerer
Fehler sein muss. Ich habe den entsprechenden Programmteil angehängt.
Die Messung starte ich indem ich mit "GICR |= (1<<INT0);" den Int0
aktiviere.
Vieleicht kann mir jemand weiterhelfen und weiß wo der Fehler liegt.


Vielen Dank schon mal

von Sonic (Gast)


Lesenswert?

Vielleicht ist der Interrupt schon ausgelöst bevor Du ihn freigibst.
Durch '1' schreiben ins entsprechendes Flag-Register kannst Du das
INT0-Flag vor der Freigabe rücksetzen (siehe Datenblatt).
die TCCRB-Anweisungen würde ich immer als erstes in die Abfrage stellen
um evtl Laufzeitunterschiede bein Starten und beim Stoppen zu vermeiden.

von Rolf Magnus (Gast)


Lesenswert?

> ich versuche gerade die Zeit zwischen 2 Impulsen zu messen. Leider
> messe ich fast Zufällige Werte, weshalb wohl irgendwo ein größerer
> Fehler sein muss.

Oder du hast tatsächlich "fast Zufällige" Impulse. Ein anderer Grund
könnte sein, daß Impulse reinkommen, während du noch darauf wartest,
daß die serielle Schnittstelle endlich bereit ist, die Daten
anzunehmen. Dann wird die Interrupt-Routine für den nächsten (oder
sonst einen späteren) Impuls verzögert ausgeführt.
Wichtige Regel: Warteschleifen in Interrupt-Routinen sind PFUI!

von Rolf Magnus (Gast)


Lesenswert?

Was ich noch vergessen habe:
Das cli() und sei() ist überflüssig. Ein sei() kann sogar schädlich
sein, denn es bedeutet, daß die Interrupt-Routine sich selbst
unterbrechen und einen Stacküberlauf produzieren kann.

von Matthias (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,

danke für eure Hilfe. Leider funktioniert es noch nicht ganz. Der
Hinweis mit dem INT0 Flag war auf jeden Fall richtig. Das habe ich
behoben, indem ich die Messung mittels
GIFR |= (1<<INTF0);
GICR |= (1<<INT0);
aktiviere. Die Wartescheleifen habe ich auch auf der ISR genommen,
indem ich die Werte einfach mal in 2 globalen Variablen ablege. Jetzt
erhalte ich auch bei jeder 2. bis 5. Messung genau den richtigen Wert.
Daher wollte ich wissen ob ich vieleich den Interrupt oder den Timer
falsch initialisiert habe? Ich möchte auf steigende Flanken an INT0
triggern und eine Prescaler von 1024 verwenden.
Ich habe euch dei entsprechenden Teile wieder angehängt und hoffe
nochnal auf eure Hilfe.

von Karl H. (kbuchegg)


Lesenswert?

> Ich habe euch dei entsprechenden Teile

Poste bitte nicht die entsprechenden Teile, sondern poste dein
Program.

In dem geposteten entsprechenden Teil' wird weder das Interrupt
Flag INTF0 gelöscht, noch der spezielle INT0 aktiviert noch
Interrupts generell eingeschaltet.

von Hubert.G (Gast)


Lesenswert?

Und man müsste nicht raten welchen µC du verwendest

von Matthias (Gast)


Angehängte Dateien:

Lesenswert?

OK, hier das ganze Programm. Ich verwende einen Mega16 mit externem
Quarz, Fuses sind alle außer BOOTSZ0 und BOOTSZ1 deaktiviert. Die
Signalquelle ist im Moment ein Funktionsgenerator der Rechtecke mit
80Hz ausgibt.

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.