Archiv verlassen und diese Seite im Standarddesign anzeigen : Zeit messen mit einem ATMega
Tux12Fun
08.03.2009, 02:20
Hallo,
mir hat sich gerade folgende Frage gestellt.
Wie kann ich am einfachsten die Zeit bei einem ATMEGA Messen,
Ich stelle mir das folgendermaßen vor. Ein pin wird auf high gesetzt. Nun müsste irgendwie ein Timer anfangen zu zählen. Wenn der Pin auf low geht würde ich gerne wissen, wie viel Zeit vergangen ist.
Das müsste doch eigentlich mit einem Timer gehen, soweit ich das richtig Verstanden haben. Meine Frage ist nun, welchen Typ von Timer muss ich für so einen kleinen Testfall anwenden. Und wie könnte so etwas in C ausshen.
Zuerst hatte ich ja an eine kleine Schleife gedacht, jedoch habe ich dann wohl das Problem, dass ich im ATMEGA nichts anders mehr während der Zeit tun kann
the_Ghost666
08.03.2009, 03:55
Welche Zeitspannen und Auflösungen möchtest du denn erreichen?
Ich würde folgendes empfehlen: Für kurze Periodendauern könntest du das Capture-Feature des Timers nehmen, z.b. Timer1, im Datenblatt ist die Konfiguration eigentlich ganz gut beschrieben. Wenn der aber über deine Maximalzeit rausspringt, dann musst du den Überlauf abfangen.
Andere Möglichkeit, die wohl flexibler ist:
Schnapp dir einen 8 oder 16Bit Timer, z.B. Timer0 oder Timer1, stell ihn auf nen Prescaler von 1 für die maximale Auflösung. Dann bindest du die avr\interrupt.h vom GCC ein und schaltest zwei Interrupts frei, einmal den Timer-Overflow und den externen Interrupt, wo dein Signal anliegen sollte. Nun zählt die Overflow-Interrupt-Routine einen Softwarezähler hoch, der Softwareteil bildet die Werte für z.B. 64-16. Bit, der Hardware Timer1 dann Bit 15-0 , somit hast du nen riesigen Wertebereich und damit lange Messzeiträume, bis ein Fehler durch Overflow passieren würde.
Der Interrupt entlastet dabei das Hauptprogramm und muss nicht mehr machen, als n Inkrement der großen Software-Variablen.
Der externe Interrupt muss als erstes den Timer abschalten, oder den Zählerstand sichern, damit die hohe Auflösung erhalten bleibt. Das dauert X Takte, die musst du vom Messergebnis abziehen. Wenn du wirklich willst, dass es genau ist, dann benutzt du priorisierte Interrupts. D.h. der Externe Interrupt darf ausgelöst werden, während der Timer-Interrupt läuft. Dazu gibt es in der GCC Doku einen Aufrufparameter, such einfach nach ISR.
Damit ist der Großteil der Zeitressourcen für z.B. Displayausgaben usw. frei. Einmal alle 65535 Takte wird der Overflow-Interrupt aufgerufen, und der andere erst, wenn die Messbedingung eintritt.
Die Hauptroutine muss dann nur den Timer1 löschen, den Externen Interrupt erlauben, dann den Timer1 starten. Ansonsten kann sie z.B. das Messergebnis umrechen, z.B. Zeit über bestimmte Strecke in Geschwindigkeit in m/s.
oberallgeier
08.03.2009, 09:55
Hi,
ich habe einen Ti mer für COMPA-Interrupt gebaut, der mir alle 50 µs einen Interrupt liefert. Die ISR zählt eine Variable hoch bis 20000 und bei diesem Wert wieder auf 1 mit Hochzählen einer Sekundenvariable. Beide sind uint_16. Damit kann ich auf 50 µs genau, das ist 1/20 Millisekunde, länger als einen halben Tag messen. Wenns noch genauer werden soll, müsste ich den aktuellen Timerstand auslesen. Beide Variablen können zwischen sei(); und cli(); sauber ausgelesen werden und liefern mir für Drehzahlmessung und -regelung von Motoren, Geschwindigkeitsberechnung eines Fahrzeugs und eben alle zeitrelevanten Operationen eine präzise "Bordzeit". Sogar ein Ser vo wird von der ISR etwas tricky aber recht codesparend angefahren.
Powered by vBulletin® Version 4.2.5 Copyright ©2024 Adduco Digital e.K. und vBulletin Solutions, Inc. Alle Rechte vorbehalten.