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.
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...
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!
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...
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.