Hallo, habe folgendes Problem: Möchte mit einem AVR Mega32 (16Mhz Quarz) die Frequenz 2er Rechtecksignale (3 bis 500 Hz, Puls/Pause = 1:1) ermitteln. Verwende folgenden Lösungsansatz: die 2 Signale gehen je auf einen externen Int. 0/1 (die ext. Int. reagieren auf jeden Flankenwechsel), mit dem Timer 0 und 2 messe ich die Puls bzw. Pausendauer (Prescaler 250kHz = 4 us/Zähltakt) Beim 1. Flankenwechsel der z.B am Int 0 erkannt wird, wird Timer1 zurück gesetzt. Da es nur ein 8Bit Timer ist muß ich in der Timer OverFlow Int. eine Variable für die Überläufe hochzählen. Wird nun der 2. Flankenwechsel erkannt, lese ich den Überlaufzähler, sowie das Timerregister aus und ermittle dadurch die Frequenz. -> Anschließend wird wieder für eine Puls bzw Pausendauer gewartet und dann erfolgt eine neue Messung. Das ganze funktioniert im Prinzip schon, allerdings erhalte ich bei bestimmten Signalfrequenzen einen "Messfehler". Das ganze liegt vermutlich daran: Wenn während ich in der Int.Routine des Ext.Int. bin ein erneuter TimerOverflow auftritt so erfolgt die Inkrementierung der Überlaufvariable erst wenn die Ext.Int Routine abgearbeitet ist -> somit ist die ermittelte Zeitdauer um den Wert 256 zu klein. Deshalb dacht ich mir ich halte zu Beginn der ext.Int Routine den Timer an, lese das Overflow Flag des Timers aus und wenn dies auf "1" ist nehm ich die Inkrementierung der Überlaufvariable in der ext.int Routine vor und lösche das Bit für den TimerOverflow Interrupt. Doch das ganze funktioniert leider noch immer nicht... Kann mir jemand sagen was ich da falsch mach ?? Oder wie ich es besser lösen kann ?? (Bei einer Eingangsfrequenz von 248 Hz, beträgt die ermittelte Frequenz mal 248Hz und mal 164Hz. Erhöhe oder veringere ich die Eingangsfrequenz um 1, dann ist die ermittelte Frequenz immer korrekt). Vielen Dank Gruß, Rolf
Hallo Rolf, ich habe mich auch schon mit dieser Materie beschäftigt und hier zwei grundlegende Verfahren vorgestellt: http://www.mikrocontroller.net/forum/read-4-230466.html >die 2 Signale gehen je auf einen externen Int. 0/1 (die ext. Int. >reagieren auf jeden Flankenwechsel), mit dem Timer 0 und 2 messe ich >die Puls bzw. Pausendauer Warum wertest Du jeden Flankenwechsel aus? Es würde genügen, wenn Du nur einen Wechsel (z.B. fallende Flanke) auswertest. Warumm zählst Du nicht einfach die Anzahl der Impulse pro Zeit, wäre doch einfacher und genauer? Bei einer Messung der Periodendauer erfolgt doch anschließend die Umrechnung f=1/T, wobei T fehlerbehaftet ist. Bernhard
Hallo Bernhard, danke für Deine Hinweise. Bei den Signalen handelt es sich um das Drehzahl und Geschwindigkeitssignal eines Motorrads. Die Variante mit "nur" 1 Sekunde lang die anliegenden Impulse hochzählen hatte ich anfangs versucht. Das hat auch super funktioniert. Der Haken daran: ich aktualisiere alle 250ms das Display mit der Drehzahl / Geschwindigkeitsanzeige. Da ich ja erst 1 Sekunde die Impulse sammeln muß war die Anzeige des Drehzahlmessers viel zu langsam und ist immer hinterher gelaufen. Darum hab ich dann auch versucht den Interrupt auf fallende und steigende Flanke zu triggern -> somit muß ich nur 500ms die Pulse zählen um die Frequenz zu bekommen. (war leider immer noch etwas zu träge am Display) Wenn ich nur 250ms die Pulse zähle und dann mal 2 rechne, dann wirds zu ungenau, da ich dan ja die Frequenz nur in 2er Schritten ermittle. Die Variante mit dem Timer wäre von der Aktualisierungs-geschwindigkeit echt super, wenn die blöden Fehler nicht drin wären... Zumal könnt ich die anliegende Frequenz sogar aufs 1/10 genau bestimmen und nicht nur auf 1 Hz genau wie bei der "Interrupt Zähl-Variante" Hab ja bei meinem ersten Beitrag nen kleinen Programmausschnitt angehängt, mach ich da vielleicht beim Abfragen des TimerOverflow Interrupt oder bei dessen Rücksetzung nen Fehler ??? Gruß Rolf.
Hallo Rolf, jetzt habe ich's verstanden, warum Du die Periodendauer messen möchtest ;) Da hast Du natürlich Recht, mit diesem Prinzip kann man sehr schnell eine Drehzahl ermitteln. >Hab ja bei meinem ersten Beitrag nen kleinen Programmausschnitt >angehängt, mach ich da vielleicht beim Abfragen des TimerOverflow >Interrupt oder bei dessen Rücksetzung nen Fehler ??? Kann ich leider nicht beurteilen, da ich bei zeitkritischen Problemen lieber in Assembler programmiere, denn da weiß man genau, was der µC bei jedem Takt gerade macht, meistens zumindest ;) Bernhard
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.