Forum: Mikrocontroller und Digitale Elektronik Messen von Frequenzen nach Sprutscher art


von Micha (Gast)


Lesenswert?

Hallo Leute.

Hätte mal eine Frage.

Bin dabei ein LC Meter nachzubauen.
µC: atmega 16 mit clk von 16MHz

Hätte eine Frage zur Frequenzmessung.

Und zwar habe ich vorerst mal versucht das ganze mit input capturing zu 
versuchen. Hat leider nicht sehr gut funktioniert da die messgenauigkeit 
bei der Frequenz die ich messe sehr nieder ist.

Mein Systemclock ist 16 Mhz das macht eine Periodendauer von ca. 62ns
Meine zu messende Frequenz ist ca. bis 1Mhz das macht dann 1µs.
Das ganze so ohne Vorteilung des signals zu realisieren ist sehr ungenau 
wie ich feststellen musste. -> kann man das noch optimieren?

So jetzt hab ich mich mal durch den Frequenzzähler von sprut gelesen...

Der kann bis 50Mhz messen...
Dazu ein paar fragen:
>>Der Timer0 ist leider nur 8 Bit groß - kann also nur bis 255 zählen. Mit >>1 
Sekunde Meßzeit, beträgt also die höchste messbare Frequenz 255 Hz. Zu >>wenig.
>>Durch Nutzung des Vorteilers läßt sich die Eingangsfrequenz bis zu 256:1 
>>herunterteilen. Die 255 entspräche dann 255*256=65280Hz. Schon besser, 
>>allerdings  verringert der Vorteiler die Meßgenauigkeit: die 65280 Hz >>werden 
nur mit 256 Hz Genauigkeit gemessen.

Laut dem Text hat der PIC die Möglichkeit das Eingangssignal durch 256 
zu teilen... habe ich das richtig verstanden?
Ist das mit den atmegas auch möglich?

Oder wird hier einfach als clk/source die zu messende Frequenz verwendet 
und dann der prescaler dementsprechend eingestellt?



von Micha (Gast)


Lesenswert?

keiner einen kommentar auf lager??
oder ist das ein faschingsscherz?

von Peter D. (peda)


Lesenswert?

Ich messe Frequenzen immer nach meiner Art:

Ich leg se aufn Counter (T0) und Capture (T1).

1:
dann beim nächsten Captureinterrupt hole ich den Wert und lese T0.

2:
danach warte ich etwa 0,5s, wobei ich eventuelle Überläufe von T0, T1 in 
Software zähle (Interrupt).

3:
dann lösche ich eventuell zwischenzeitliche Captures und mache wieder 
Schritt 1.


Nun habe ich die vergangene Zeit zwischen den Captures und die Anzahl 
der Eingangsperioden und voila:

f_in = f_quarz * (T0 - T0_alt) / (T1 - T1_alt)

Damit habe ich ne gleichbleibend hohe Genauigkeit, völlig egal welche 
Frequenz (0,5Hz ... 5MHz).

Und wenn nach 2 Sekunden immer noch kein Capure kam, zeige ich 0Hz an.


Etwas tricky ist noch, wenn Capture- und Overflow-Interrupt gleichzeitig 
sind, dann muß man das höherwertigste Bit des HW-Timer-Wertes auswerten.


Peter


P.S.:
Bei 50MHz braucht man nen Vorteiler, z.B. 74HC393, der ändert aber 
nichts an der Genauigkeit.

von Micha (Gast)


Lesenswert?

Hmm die erklärung is mir nicht so klar...

Theoretisch könnte ich das ganze ja auch nur mit einem Timer realisieren 
oder?
Jeder Overflow-Interrupt wird per Software mitgezählt und jeder 
Capture-Interrupt wird als eintreffender Impuls gezählt...

Ich bitte darum das mit den 2 Timern nochmals genauer zu erklären.
thx

schöne Grüße


von Peter D. (peda)


Lesenswert?

Über etwa 500kHz könnte es schwierig werden, alle Cature-Interrupts 
mitzuzählen, deshalb den T0 als Counter parallel.


Peter

von Micha (Gast)


Lesenswert?

Sry aber ich verstehe den zusammenhang nicht ganz.

Ich starte das Input captureing mit einem Timer.
Wenn die erste impuls eintrifft dann setzte ich das counterregister 
zurück auf 0 und lasse ihn laufen.
Bei jedem input-caputure interrupt inkrementiere ich eine variable und 
jeden overflow protokolliere ebenfalls.
Nach einer von mir definierten Zeit eben 0,5 sec oder so kann ich die 
anzahl der input captures auswerten...

Was macht das jetzt für einen unterschied wenn ein zweiter timer 
parallel läuft?
Warum könnte es nur mit einem Timer schwierig werden die 
Capture-interrupts mitzuzählen?

schöne Grüße
Micha

von Christoph Kessler (db1uq) (Gast)


Lesenswert?

Die PICs synchronisieren ihren Timer-Eingang nicht mit dem 
Controllertakt, können daher bis etwa 50 MHz direkt zählen.
AVR können maximal die halbe Taktfrequenz zählen, da das Eingangssignal 
zunächst mit dem Takt synchronisiert wird.

von Micha (Gast)


Lesenswert?

Peter Danegger..

Wie ich aus deiner Gleichung entnehmen konnte misst du mit beiden timern 
mit dem gleichen prescaler. Höchstwarscheinlich 1 oder?

f_in = f_quarz * (T0 - T0_alt) / (T1 - T1_alt)

Was mir noch nicht ganz klar ist, ist wie du die zeitliche 
messdauerbegrenzung von 0,5sec machst.

Bei 10Mhz sind 10 Mill takte pro sec. d.h. 5 Mill takte dauert die halbe 
Sekunde...
Bestimmst du dann die Messzeit in dem du abfragst: soundsoviel überläufe 
und der timer steht jetzt bei dem wert. Zeit vorbei...

Für was misst du die Overflows vom capture-timer?

Können mir andere auch beantworten falls sie das peilen?
thx greets

von Peter D. (peda)


Lesenswert?

Micha wrote:

> Wie ich aus deiner Gleichung entnehmen konnte misst du mit beiden timern
> mit dem gleichen prescaler. Höchstwarscheinlich 1 oder?

Was sonst, ich will ja ne möglichst hohe Auflösung.
Je größer der Zählwert von T1, umso größer die Auflösung, da der 
prinzipielle Fehler ja ein Timertick ist.

T0 als Counter dient nur dazu, bei hohen Frequenzen die Periodenanzahl 
zu zählen, da mir sonst die Capture-Interupts die CPU zuballern würden 
(2 Zyklen reichen nie für einen Interrupthandler, 2 * 256 Zyklen dagegen 
schon).


> Was mir noch nicht ganz klar ist, ist wie du die zeitliche
> messdauerbegrenzung von 0,5sec machst.
>
> Bei 10Mhz sind 10 Mill takte pro sec. d.h. 5 Mill takte dauert die halbe
> Sekunde...
> Bestimmst du dann die Messzeit in dem du abfragst: soundsoviel überläufe
> und der timer steht jetzt bei dem wert. Zeit vorbei...

Auf genaue 0,5s kommts nicht an, da ich ja eh noch bis zum Ende der 
letzten Periode warte, daher reicht das Zählen der Überläufe.
Man könnte aber auch mit dem Compareinterrupt genau 5000000 Zyklen 
warten.


Peter

von Micha (Gast)


Lesenswert?

>T0 als Counter dient nur dazu, bei hohen Frequenzen die Periodenanzahl
>zu zählen, da mir sonst die Capture-Interupts die CPU zuballern würden
>(2 Zyklen reichen nie für einen Interrupthandler, 2 * 256 Zyklen dagegen
>schon).

Um die Captures zählen zu können musst du ja den Interrupt benutzen 
oder?
2*256 zyklen?

micha

von Peter D. (peda)


Lesenswert?

Micha wrote:

> Um die Captures zählen zu können musst du ja den Interrupt benutzen
> oder?
> 2*256 zyklen?


Also T0 und ICP werden beide parallel geschaltet und mit der 
Eingangsfrequenz verbunden.

Den Captureinterrupt nehme ich nur ein einziges Mal, nachdem die 0,5s 
abgelaufen sind.

Natürlich sind bei hohen Frequenzen schon mehrere Capture erfolgt, ehe 
ich im Interrupt das Captureregister ausgelesen hab.

Ich muß also den T0 möglichst unmittelbar vor dem Captureregister 
auslesen, damit ich die genaue Periodenanzahl habe.
Ich kann also bei hohen Frequenzen noch einen zusätzlichen Fehler von 
einer Periode erhalten.


Peter

von Micha (Gast)


Lesenswert?

>Also T0 und ICP werden beide parallel geschaltet und mit der
>Eingangsfrequenz verbunden.

Du verwendest als clk/source die zu messende frequenz?

von Micha (Gast)


Lesenswert?

Also clk-source für die 2 timer meine ich..

sg

von Bernhard S. (bernhard)


Lesenswert?


Schau mal hier:

LC-METER:
Beitrag "LC-METER / LC-Messgerät ATmega8 Assembler"


Freuquenzzähler:
Beitrag "einfacher 5 MHz Frequenzzähler (Assembler) ATmega8"

Ist nur in Assembler geschrieben, aber vielleicht hilft's ;)

von Hannes L. (hannes)


Lesenswert?

@Micha:

Timer0 hängt am Messeingang und zählt die Takte

Timer 1 hängt am Controllertakt und stellt die Zeitreferenz für ICP zur 
Verfügung.

ICP wird 1/2 s lang deaktiviert, um die CPU nicht mit zu schneller Folge 
von Interrupts zuzumüllen. In dieser Zeit zählt Timer0 die ankommenden 
Impulse. Die ermittelte ICP-Zeit gilt dann für die Anzahl der gezählten 
Impulse.

...

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.