mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Frequenzmessung mit Atmega16


Autor: putzer_philipp (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo!

Ich versuche seit ein paar Tagen eine Frequenzmessung mit dem AVR zu
machen.

Grundidee war folgende:
- Timer 0 löst nach Ablaufen einer Torzeit von 100msec ein Interrupt
aus
- In der Interrupt-Routine werden die fallenden Flanken mit Timer 1 als
Zähler gezählt
- Anschließend werden die Pulse mit 10 multipliziert und fertig


Um einen gescheiten Rechteckgenerator zu haben, verwendete ich Timer 2
und schloss ihn direkt an den ext. eingang des Zählers.

Das Problem ist nun folgenedes: bei einer errechneten (!!!) Frequenz
von 976Hz an OC2, also am Ausgang des Timer 2 bekomme ich eine Frequenz
von 780Hz am Display angezeigt.
Hingegen bei einer Frequenz von 100Hz an OC2 den Wert 100 am Display.
Der Fehler ist dann nocht nichtmal linear, dass man ihn einfach
auskorrigieren könnte.

Kann denn der Fehler darin liegen, dass beim Auftreten eines
Interruptes die ISR zu lange ist, und dadurch Flanken/Pulse verloren
gehen?

Ich hänge mal die C-Datei an, in der aber Timer 1 als Zeitgeber und
Timer 0 als Zähler funktionieren. Habe das auch andersherum probiert,
das ergebins war aber genau das selbe.

Autor: AVRNIX (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
abo

Autor: johnny.m (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn Du mit dem Overflow Interrupt arbeitest, musst Du Dich über
Ungenauigkeiten nicht wundern. Die Generierung präziser Zeitintervalle
macht man bei den AVRs sinnvollerweise mit einer Compare-Einheit und
dem betreffenden Timer im CTC-Modus. Dann entfällt nämlich das
(unpräzise) Nachladen des TCNT-Registers. Bei Timer2 hast Du das ja
schon korrekt gemacht. In Deinem Fall dürfte das zwar keine besondere
Abweichung ergeben, aber zur Information... Deine Vermutung, die ISR
sei zu lang, dürfte jedenfalls keine Rolle spielen. Die ISR ist recht
kurz und bei den Frequenzen geht da wahrscheinlich maximal eine Flanke
verloren (Wenn die ISR vielleicht inklusive aller pushs und pops 30-40
Taktzyklen braucht, dann sind das bei 8 MHz 3,75-5µs, was Frequenzen
von 200-300kHz entspräche). Daran liegts also mit Sicherheit nicht.

Eine Frequenzmessung im Bereich derart niedriger Frequenzen ist besser
mit einer Periodendauermessung anstatt mit einer direkten
Frequenzmessung machbar. Auch das nur am Rande...

Mir ist auch ein wenig unverständlich, wieso Du für die Frequenz einen
float spendierst. Ein unsigned int tuts auch.

Bei Frequenzen über 1000Hz gibts dann sicher Probleme, wenn
Timer/Counter0 innerhalb der Torzeit überläuft. Da musste dann auf
jeden Fall noch nen Interrupt spendieren (im Kommentar steht auch
irgendwas in der Richtung...).

Das ist so das, was mir bei dem Code auf Anhieb auffällt...

Autor: putzer_philipp (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke, für die schnelle Antwort!

Habe nun den Timer 1 im Compare-Betrieb, also wia T2, nur ist das
Ergebnis in etwa das Gleiche.

@johnny.m
Wie geanu mache ich eine Periodendauermessung am besten?

Genügt es einfach die Zeit zwischen zwei steigenden/oder fallenden
Flanken zu messen, und daraus dann die frequenz berechnen lassen?
Oder ist es doch etwas komplizierter?

Schon mal Danke im Voraus!

Autor: johnny.m (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wieso sollte es komplizierter sein? f = 1/t (f = Frequenz, t =
Periodendauer). Man zählt also nicht die Flanken in einer Torzeit (die,
wie man sich leicht vorstellen kann, bei niedrigen Frequenzen immer
länger gewählt werden muss, um noch eine brauchbare Auflösung zu
erhalten), sondern man misst die Zeit zwischen zwei Flanken. Das geht
sehr schön mit der Input Capture-Funktion des Controllers. Die einzige
kleine Schwierigkeit dabei ist die Umrechnung der gemessenen Zeit in
eine Frequenz.

Es hat vor einer Weile einen Thread hier zu dem Thema gegeben, den ich
aber jetzt auf die Schnelle nicht wiedergefunden habe. Da hatte ich die
Verwendung der Input Capture Unit ziemlich detailliert beschrieben (Ich
sollte mir vielleicht mal ein paar Templates für solche Fälle machen,
damit ich nicht immer alles noch mal tippen muss...). Am besten Schaust
Du Dir schon mal im Datenblatt die Funktionsweise der Input Capture Unit
an (falls Du es nicht schon getan hast) und wenn Du weitere Fragen hast,
dann habe ich vielleicht in der Zwischenzeit den alten Thread
rausgekramt...

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.