Forum: Mikrocontroller und Digitale Elektronik Drehzahlmesser in ASM


von jaedle (Gast)


Lesenswert?

Hallo,
ich habe ein kleines Problem etwas in ASM zu realisieren.

Ich möchte die Zeitspanne, die zwischen zwei Zündimpulsen eines
Verbrennungsmotors geschieht abgreifen (Schwingungsdauer). Hiervon
möchte ich dann den Kehrwert (Frequenz) nehmen, um somit die Drehzahl
des Motors auf eine Minute hochzurechnen.

Das Signal liegt bereits mit TTL-Pegel vor und bewirkt bei jedem
Interrupt einen Zündimpuls beim mc.

Als mc verwende ich einen Atmel Mega16 und möchte diesen mit Assembler
programmieren. (Ich hatte bereits ein entsprechendes funktionierendes
C-Programm geschrieben, nur leider war das sehr recoursen-lastig -->
Wechsel zu ASM.)

Jetzt habe ich folgendes Problem:
Nach einigen mathematischen Vereinfachungen berechne ich die Drehzahl
mit folgendem Ausdruck:

UPM = 3750000 / Anzahl_der_Timer_interrupts.
(Anzahl_der_Timer_interrupts liegt zwischen 350 und 3500.)

Mein Problem ist jetzt, dass ich ja eine Division eines 24-Bit Integers
durch einen 16-Bit integer.. ist sowas ohne Probleme in ASM möglich? Wie
könnte ich das umgehen?


Danke schonmal für eure Bemühungen!

mfg,
#jaedle

von Peter Dannegger (Gast)


Lesenswert?

"nur leider war das sehr recoursen-lastig --> Wechsel zu ASM"

Das wird dann aber nicht helfen, Du mußt schon den Programmablauf
optimieren. Dann schnarcht auch in C Dein MC die meiste Zeit nur rum.


Ein Mensch ist maximal in der Lage 2..5 Meßwerte pro Sekunde
abzulesen.

Und Du kannst mir nicht erzählen, daß da kein C-Programm mitkommt.
Selbst float-Zahlen kannst Du ohne Probleme nehmen (bei AVRs ab 8kB
Flash).

Im Gegenteil, die Rechenroutinen sind in C meistens hochoptimiert, d.h.
Deine Assemblerversion wird sogar noch mehr Rechenzeit benötigen (wenn
Du sie nicht aus dem C-Listing abkopierst).


Peter

von Peter Dannegger (Gast)


Lesenswert?

"bewirkt bei jedem Interrupt einen Zündimpuls beim mc."

:-)

Ich glaube kaum, daß der mc auch nur einen Zündimpuls überlebt.

Du meintest wohl:

"bewirkt bei jedem Zündimpuls einen Interrupt beim mc."


Peter

von Der Elektrische Reiter (Gast)


Lesenswert?

Muss die hohe Genauigkeit wirklich sein?

Stell dir vor, du kannst mit 8Bit Genauigkeit leben. (Das sind dann ein
Fehler von 1/256 oder ca. <0,5%. Die Abweichung beträgt dann bei
10.000U/min 50U/min) Dann ist es möglich durch vorherige Teilung das
Problem mit einer 8-bit Division zu erschlagen.

Beispiel:
Timerintervall wird durch 16 geteilt. Das Intervall läuft dann von
350/16=21 bis 3500/16=218. Ich verwende hier die Division durch 16, da
Pozessoren i. allg das Teilen durch ganze Zweierpotenzen lieben. Es
lässt sich leicht durch schieben/rotieren nach rechts erreichen.
Vieleicht kannst du auch den Timer um den Faktor 16 langsamer laufen
lassen. Dann sparst du dir sogar diese Division.

Damit die Rechnung noch stimmt, mußt Du den Zähler auch durch 16
Teilen. Das macht dann 3750000/16=234375. Das ist aber immer noch recht
unhandlich. Eine Division durch 10 ergibt 23437. Du mußt die bei der
Ausgabe allerdings merken, das das Ergebnis um den Faktor 10 zu kelin
ist. Anstelle von 100U/min kommen nur 100U/min raus. Dieser Wert
(23437) passt in 16Bit. Nun muß nur noch 16Bit durch 8Bit geteilt
werden. Das sollte kein Problem mehr sein.

cu

von jaedle (Gast)


Lesenswert?

Zu erst muss ich vielleicht noch ein Stück ausholen, was der MC alles
noch leisten soll:

Drehzahlbestimmung, Ausgabe auf Drehspulinstrument (PWM), Auslesen
eines Potis (Ersatz für mechanischen Gaszug), Ansteuerung eines Servos
(Drosselklappe stellen), Temperaturerfassung, Speicherung aller
Messwerte alle 5 bzw. 10 Sekunden.


@Peter:
"bewirkt bei jedem Interrupt einen Zündimpuls beim mc."
ganz klar, Murks von mir - aber es war spät ;)

"Das wird dann aber nicht helfen, Du mußt schon den Programmablauf
optimieren. Dann schnarcht auch in C Dein MC die meiste Zeit nur
rum."
Ich habe versucht das ganze soweit zu optimieren wie möglich, nur die
Programmflusssteuerung ist mir einfach zu ungenau. Deswegen möchte ich
hier auf Assembler setzen.

"Ein Mensch ist maximal in der Lage 2..5 Meßwerte pro Sekunde
abzulesen."
Das ist mir klar. Anfangs soll eine Reihe von 7-Segment Anzeigen
herhalten, später evtl. ein Drehspulinstrument oder ein LCD-Display.

"Und Du kannst mir nicht erzählen, daß da kein C-Programm mitkommt.
Selbst float-Zahlen kannst Du ohne Probleme nehmen (bei AVRs ab 8kB
Flash)."
Float muss gar nicht sein, da nur eine Division, aber ich möchte
einfach mehr Kontrolle haben --> Assembler.

@Der Elektrische Reiter:
Werde mir deine Methode anschaun. Ein Messwert unter 2000UPM oder
größer als 8000UPM ist sehr unwahrscheinlich (2-Takt 1-Zylindermotor
von einer alten Kettensäge, 1PS..)

von jaedle (Gast)


Lesenswert?

Achja, um es natürlich nicht zu vergessen:

Danke für Eure Antworten!

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
Noch kein Account? Hier anmelden.