mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Frequenz messen


Autor: sammy (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi, ich moechte mit einem 2313 eine Frequenz messen und dann die mit
vordefinierten Werten vergleichen und dann die Abweichung eber LEDs
anzeigen.
Die Frequenz wird vor dem 2313 verstaerkt, so das sie als 0 und 1
erkannt wird, es muessen also diese Wechsel pro Zeit gezaehlt werden.
Wie schliesse ich das ganze am besten am Controller an?
Ueber Codeschnipsel wuerde ich mich auch freuen!

Autor: Matthias (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

was für eine Frequenz (welcher Größenordnung)?

Bei sehr kleinen Frequenzen (bis ein paar 100 Hz) kann man per Software
abtasten. Und aus der ermittleten Periodendauer dann die Frequenz
bestimmen.

Bei Frequenzen bis zu ein paar kHz arbeitet man mit der ICP-Funktion
eines Timers. Auch diese liefert dann die Periodendauer aus der man die
Frequenz berechnen kann.

Wenns noch mehr wird (bei AVR's <8MHz bei 50:50 Tastverhältnis direkt)
zählt man für eine bestimmte Zeitperiode die Anzahl der Pulse und hat
dann im Prinzip die Frequenz direkt vorliegen.

Wirds noch schneller muß man mit (einstellbaren) Vorteilern arbeiten.

Matthias

Autor: sammy (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die Frequenzen liegen zwischen ca 0Hz bis 8000Hz

Autor: sammy (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ach ja, muss der Eingang zur Frequenzmessung an einem bestimmten I/O Pin
sein, oder ist das egal?

Autor: crazy horse (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Frequenz 0Hz messen wird schwierig :-).
Zum groben Ablauf:
Ich würde den ICP benutzen, nehmen wir mal 8MHz Quarz und Vorteiler 8
für den Timer1, also 1µs Takt.
Damit kannst du ausreichend genau messen, allerdings läuft der Timer
bei niedrigen Eingangsfrequenzen über, muss also per Software erweitert
werden.
Dazu schreibst du dir eine T1OV-Interruptroutine, die bei jedem
Überlauf ein Register incrementiert, damit kommst du auf eine max.
Peridendauer von 1µs*65536 (Timer1)* 255 (zus. Register) 16,77s, das
entspricht ca. 0,06Hz.
Um aus dem 24bit-Ergebnis die Frequenz in Hz zu berechnen, brauchst du
nur noch eine Division 1.000.000/Messwert.
Willst du es genauer, kannst du den Timer1 ohne Vorteiler betreiben,
dann evtl. mit einem 16bit-OV-Zähler arbeiten.

Autor: Mike (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

klappt das mit dem Frequenz messen auch wenn das Signal über eine
der ext. Interruptpins bekomme? Dann muß ich die Zeit zwischen zwei
Signalen doch einfach nur "per Hand" messen und dann genau so
rechnen.
Zum messen nehme ich einfach einen frei laufenden Counter und berechne

die Zeit zwischen zwei Signalen. Klappt das so oder sollte ich das
lieber doch anders machen?

Mike

Autor: Matthias (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

kannst du auch so machen. Bei 8kHz ghet das noch relativ gut.

Matthias

Autor: Günther (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich will nicht extra noch ein Beitrag auf machen und erweiter diesen
mal.

Schafft ein Mega161 mit 16MHz es an PD2(INT0) etwa 17kHz zu messen?
Könnte ich die auch an anderen 'normalen' Eingängen messen?
Was passiert, wenn die F bis etwa 100kHz ansteigt? Ich denke mal worst
case gehen ein paar Takte verloren, oder?
Hintergrund: Wenn F über etwa 16kHz steigt soll ein Ausgang schalten.
Dabei ist es aber egal ob F dann 18kHz oder 200kHz hat. Hauptsache
alles über etwa 16kHz wird als mehr erkannt.
Die Frequenz die max. anliegen kann wird wohl 120kHz sein.
Eingangssignal ist Rechteck mit TTl-Level.

Autor: Günther (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Keiner eine Antwort

Autor: Hmm... (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der AVR kann schon recht kurze Pulse am Eingang erkennen, sofern sie an 
einen  interruptfähigen Pin ankommen. Problematischer wird es dann, noch 
eine Anwendung laufen zu lassen.

Beispiel:

120 kHz Signal an AVR mit 10 MHz Takt macht alle 83 Befehle einen 
Interrupt. Da bleibt nicht viel Zeit um noch groß anderes zu rechnen. Um 
allerdings nur eine Frequenz zu errechnen und auf die UART zu packen 
sollte es reichen ;)

Autor: Kai G. (runtimeterror)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sollte locker gehen... um mal den Grenzfall zu betrachten: 16 MHz / 200 
kHz gibt 80 Taktzyklen pro Messung (deckt sich etwa mit  Hmm...s 
Rechenbeispiel).

Kann jetzt gerade nur für Assembler sprechen, aber C sollte da auch noch 
locker drin sein:
Für jeden edge rise/fall
- Interrupt-Jump
- Timer-Reset
- Messwert ablegen
- bedingter Sprung, wenn Messreihe voll
- return
Sollte in unter 20 Taktzyklen zu schaffen sein.

Dein Programm hat also noch mindestens 1 - 20/80 = 75% Rechenzeit für 
nicht zeitkritische Sachen übrig (wenn ich nicht grob fahrlässig 
verrechnet habe :) ). Für die Übermittlung, Berechnung und/oder Ausgabe 
der Messergebnisse kannst du auch kurz die Messung anhalten und 
anschließend wieder starten - kann aber bei niedrigen Frequenzen die 
Messung verfälschen, wenn man nicht aufpasst.

Wenn du alle Nulldurchgänge messen willst und nicht nur rising/falling 
edge, verdoppelt sich logischer Weise die Anzahl der Interruptaufrufe.

Ab Frequenzen wo die Interrupts zu viel Rechenzeit verbrauchen kannst du 
ein einfaches Polling verwenden - dann macht der Mikrocontroller aber 
nichts mehr nebenher. Ich würde hier aber spätestens auch anfangen nach 
anderen Lösungen zu suchen.

Sollte die Frequenz deutlich höher als dein Limit werden macht sich das 
vielzitierte Nyquist-Shannon-Abtasttheorem 
(http://de.wikipedia.org/wiki/Nyquist-Shannon-Abtasttheorem) wieder 
bemerkbar und die Messergebnisse stimmen nicht mehr.

Autor: Stephan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Günther
Sorry, jetzt hast du drei Jahre am selben Problem rumgebastelt und immer 
noch keine eigene Lösung? Anstatt nochmal drei Jahre auf eine Lösung zu 
warten beginn doch ein Studium oder arbeite dich sonst tiefer in die 
Materie ein.
Getreu dem Motto:
"Hilf dir selbst, dann hilft dir Gott"

Autor: THM (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Input-Capture-INT enabled, die Überläufe zählen und die Start- und 
Stopzeit (Zählerstände des Timers beim ICP-INT) merken, dann mit der 
Taktfrequenz verrechnen. Z.B. mega32 bei 16MHz so:
Frequenz = (ICP_OVF * 65536) + stoptime - starttime;  // Zählerstand ermitteln
Frequenz = (16000000/Frequenz);// SYSCLK*32 wegen PWM-Mode,
Status &= ~_BV(ST_ICP);    // Frequenz berechnen
TIFR |= _BV(ICF1);
Auf dem Tiny2313 dürfte das einige Resourcen fressen.

Siehe auch in der Codesammlung (nach 'Frequenz' suchen).

Autor: THM (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Input-Capture-INT enabled, die Überläufe zählen und die Start- und 
Stopzeit (Zählerstände des Timers beim ICP-INT) merken, dann mit der 
Taktfrequenz verrechnen. Z.B. mega32 bei 16MHz so:

Frequenz = (ICP_OVF * 65536) + stoptime - starttime;  // Zählerstand ermitteln
Frequenz = (16000000/Frequenz);
Status &= ~_BV(ST_ICP);    // Frequenz berechnen
TIFR |= _BV(ICF1);
Auf dem Tiny2313 dürfte das einige Resourcen fressen.

Siehe auch in der Codesammlung (nach 'Frequenz' suchen).

So isses besser ;)

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.