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!
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
ach ja, muss der Eingang zur Frequenzmessung an einem bestimmten I/O Pin sein, oder ist das egal?
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.
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
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.
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 ;)
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.
@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"
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:
1 | Frequenz = (ICP_OVF * 65536) + stoptime - starttime; // Zählerstand ermitteln |
2 | Frequenz = (16000000/Frequenz);// SYSCLK*32 wegen PWM-Mode, |
3 | Status &= ~_BV(ST_ICP); // Frequenz berechnen |
4 | TIFR |= _BV(ICF1); |
Auf dem Tiny2313 dürfte das einige Resourcen fressen. Siehe auch in der Codesammlung (nach 'Frequenz' suchen).
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:
1 | Frequenz = (ICP_OVF * 65536) + stoptime - starttime; // Zählerstand ermitteln |
2 | Frequenz = (16000000/Frequenz); |
3 | Status &= ~_BV(ST_ICP); // Frequenz berechnen |
4 | TIFR |= _BV(ICF1); |
Auf dem Tiny2313 dürfte das einige Resourcen fressen. Siehe auch in der Codesammlung (nach 'Frequenz' suchen). So isses besser ;)
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.