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
"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
"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
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
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..)
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.