Archiv verlassen und diese Seite im Standarddesign anzeigen : Drehzahlmessung mit ATmega16
Sauginius
09.06.2004, 21:37
Hallo,
ich habe vor mir einen Drehzahlmesser mit dem ATmega16 zu bauen. Ich hab auch schon etwas experimentiert, aber leider müsste ich wissen wie das mit dem Counter und Timer funktioniert.
Also ich hab mir das so vorgestellt:
Sobald eine Zündung erfolgt wird per Interrupt der Timer ausgelöst und beginnt zu zählen. Kommt wieder eine Zündung stopt der Timer und der µC kann dann die Drehzahl ausrechnen und auf einem Display ausgeben.
Was die Hardwäre betrifft, das ist erstmal egal. Es geht mir einfach nur um den Timer bzw. Counter.
Ich programmiere in Assembler, also nur zur Info.
Hi,
du hast das doch schon alles richtig beschrieben wie man es machen muss. Der Rest ( wie man genau welche Register setzen muss usw. ) steht im Datenblatt.
Wo ist denn jetzt genau das Problem ??
Für Timer1:
In der Interruptroutine die durch deine "Zündung" ausgelöst wird fragst du ab ob der Timer schon läuft. Wenn nicht startest du ihn ( Prescalerbits in TCCR1B setzen ). Wenn er schon lief, dann liest du den Wert aus den TCNT1L und TCNT1H aus, berechnest daraus irgendwie deine Geschwindigkeit, löscht das Timer Register wieder und startest den Timer evntl. wieder ...
Ich hoffe das war verständlich ??
MfG Kjion
Sauginius
09.06.2004, 22:05
Hallo,
das Problem liegt daran das ich beim Dattenbaltt nicht richtig durchblicke. Die tausend Abkürzungen für Register usw.
Schau mal hier:
Ist zwar ein AVR Einstiegskurs in C, aber dort sind auch die Register für die Timer aufgelistet (ZIP-Datei mit HTML Seiten):
http://www.mypage.bluewin.ch/ch_schifferle/Atmel.zip
Könnte Dir weiterhelfen.
Sauginius
10.06.2004, 19:01
@matren
ja es hat mir weitergeholfen. Ich habe soweit alles auf die Reihe bekommen.
Aber jetzt kommt der schwierigere Teil: Die Rechnung!
Von Zündzeitpunkt zu Zündzeitpunkt bedeutet eine Umdrehung. Der Timer erfasst die Zeitzyklen die der Motor für eine Umdrehung braucht. Demnach komme ich auf diese Formel wenn ich das Ergebnis in 1/min haben will.
60/[Zyklen*(CPU Takt/1024)]
Der Term in der () entspricht dem Prescaler der auf 1/1024 eingestellt ist.
Wie führe ich diese Rechnung aus? Es handelt sich dabei um einen 16Bit Timer.
Wie kann ich ein Registerpaar (16Bit) mit einer Zahl multiplizieren oder dividieren?
Wie kann ich ein Registerpaar (16Bit) mit einer Zahl multiplizieren oder dividieren?
Such mal im Internet nach den entsprechenden Algorythmen ( multiplizieren gibts bei den ATmega's teilweise sogar als Befehl -> siehe Datenblatt : Hardware Multiplier bzw. "mul"-Befehl ). Da sollte sich auf jeden Fall was finden lassen. Selber schreiben würde ich nicht machen, da es sowas wie gesagt schon gibt ...
MfG Kjion
Sauginius
10.06.2004, 20:13
Ich hab hier (https://www.roboternetz.de/phpBB2/viewtopic.php?t=88)im Forum was gefunden, leider verstehe ich es nicht.
Ich weiss das durch rotieren nach links die Zahl mit zwei multipliziert und beim schieben nach rechts dividiert wird
Kann es sein das der µC nur mit 2 multiplizieren bzw. dividieren kann?
Sauginius
10.06.2004, 22:27
Oh ich hab einen Fehler in der Formel
60/[Zyklen*(1/CPU Takt/1024)]
Man braucht ja die Zeit und nicht die Frequenz
AlexAtRobo
11.06.2004, 12:14
hm, je nach dem wie genau du messen willst, und was der mega noch alles machen soll, kannst du das einfacher lösen. Stell doch den Timer 1 auf eine 16tel Sekunde (oder sonst irgendein vielfaches von 2) ein (kann man gut über den Takt ausrechnen). Den Timer 0 nimmst du als Counter. Immer wenn Timer1 abläuft, schau nach wieviele Pulse Counter 0 gezählt hat, 4 mal schieben und schon hast du /min. Counter rücksetzen und wieder von vorne.
lg
Alex
Sauginius
11.06.2004, 15:48
Das verstehe ich nicht so ganz. Wenn ich 1/16Sekunde 4mal schiebe komme ich doch auf eine Sekunde oder?
AlexAtRobo
15.06.2004, 10:33
Von da brauchst du "nur" mehr x60 multiplizieren. Also am besten nochmal 4x Schieben, dann 1x den Originalwert abziehen -> x15. Das noch 2x Schieben entspricht x4. x15 x 4 => x60
Wenn du möchtest habe ich ein Kompletten schaltplan mit Code in "Codevision" für dich. Wenn es dir hilft bei mir Funktioniert es.!!!
MFG: Fichte
Gottfreak
16.06.2004, 00:35
Gerade bei solchen Berechnungen liegen auch die großen Vorteile von Hochsprachen wie Basic oder C. Bei einem Prescaler von 1024 ist der Genauigkeitsverlust durch die paar Takte, die ein Compiler vielleicht verschenkt, sicher zu vernachlässigen(wenn bei dir an der Stelle nicht der Weg das Ziel ist).
Sauginius
16.06.2004, 17:33
@Fichte
Danke für dein Angebot aber ich kann nur in Assembler programmieren. Außerdem möchte ich ja auch was lernen.
Vielleicht kannst du mir ja bei einem anderen Problem weiterhelfen. Ich habe z.Z. ein Programm für die Drehzahlmessung geschrieben und möchte das errechnete Ergebnis (16Bit) an ein LCD ausgeben.
Also wenn ich zum beispiel diese Zahl errechnet habe:
0b0001100101100100 = 6500(Dezimal)
dann muss ich die 6,5,0,0 jeweils als (8Bit) Dualzahl an das LCD
schicken. Wie kann ich das realisieren?
AlexAtRobo
16.06.2004, 22:07
Schau mal auf www.avr-asm-tutorial.net
Herr Schmidt hat dort alles schön zusammengefasst und sogar als PDF zum Ausdrucken zusammengestellt. Dort erklärt er ausführlich, wie man mit Assembler von Binär auf BCD auf ASCII kommt.
Ich habe das auch schon benutzt und funktioniert einwandfrei.
lg
Alex
partyboarder
04.11.2004, 18:09
Hallo Ihrs
Ich habe sowas ähnliches schonmal in der FH programmieren müssen.
ich habe zuerst mit auch mit timer start/stop gearbeitet, was zwar ergebnisse geliefert hat aber insgesamt sehr langsam war.
Ich habe dann mir das gaze nochmal genauer angeschaut und bin dann auf input capture gekommen. dabei läuft der timer die ganze zeit und sobald ein signal kommt legt er den aktuellen wert in einem extra register ab und cleared den counter, der danach wieder hochläuft bis zum nächsten signal. man muss dann nur noch den wert aus dem register rauslesen und weiterverabeiten. dadurch entfällt das ganze start/stop gedöns und der prozessor macht das alles in der hardware.
okay wir haben da mit einem hitachi H8S/2357 prozessor gearbeitet aber soweit ich mich erinnere hat der atmega 16 auch input capturing
gruß
mac
Whow mac
Ich will die Impulslaenge von einem Empfaenger einer Fernsteuerung an die Servos dekodieren, dabei kommen die Impulse der z.B. 8 Kanaele immer zeitlich direkt nacheinander so dass mich die Verzoegerung beim Umschalten beunruhigt. Deine Technik ware ideal. Werde es pruefen. Danke
AlexAtRobo
08.11.2004, 09:23
Hallo,
vom Timing her würde ich mir nicht allzuviele sorgen machen. Wenn du z.B. mit 4 oder 8Mhz taktest, braucht 1 Befehl 250ns bzw. 125ns, erreichen mußt du für Servos 1ms - 2ms. Während dieser Zeit laufen also 4000-8000 Takte. Das geht problemlos. Wenn du in Assembler programmierst, kannst du die Takte deines Programms zählen und gegebenfalls als Korrekturwert noch hinzufügen. Nur wird der Servo ein paar us Fehler gar nicht darstellen, deswegen brauchst du dir darum nicht den Kopf zu zerbrechen. Zwischen den Einzelnen Servoimpulsen ist auch noch viel zeit über.
Ich hab mir erst kürzlich auch so etwas ähnliches gebaut. Ich messe den Servoimpuls und Schalte je nach Impulslänge verschiedene Ausgänge (5 Stück).
lg
Alex
Moin
ich hab mal hier nen link zur doku von o.g. FH Projekt
http://www.geisterstunde.org/report/
und dann Content->TPU Second Attempt.
gruß
mac
Powered by vBulletin® Version 4.2.5 Copyright ©2024 Adduco Digital e.K. und vBulletin Solutions, Inc. Alle Rechte vorbehalten.