Guten Tag, ich benutze das Avr Studio 4.14. Ich möchte mir ein paar Konstanten zur präprozessorzeit vom Assembler ausrechnen lassen. Jetzt habe ich aber festgestellt das dieser mir die Fließkommazahlen einfach hinter dem Komma abschneidet. Hier mal das Beispiel: .equ Drehzahl = 60 .equ MessInterval = 0.1 .equ CPUFrequenz = 8000000 .equ PWMFrequenz = CPUFrequenz/256 .equ DrehzahlFaktor = (((Drehzahl/60)/MessInterval)/1000)*500 Die Konstante "DrehzahlFaktor" soll nacher im Code an den entsprechenden stellen eingefügt werden. Damit ich den wert nicht jedesmal neu ausrechnen will, habe ich die Formel dazu Geschrieben und ich brauch nur die Drehzahl ganz oben zu ändern. Ist jetzt eigentlich auch nicht relevant, denn das eigentliche Problem ist, das der AVR Asembler mir bei der Konstante "MessInterval" die 1 hinter dem komma abschneidet. Das erzeugt dann natürlich die Fehlermeldung das nicht durch 0 geteilt werden kann. Was kann ich tun?
Hi Und das überrascht dich? Was geht ist (im Assembler2) z.B .equ DrehzahlFaktor = Q7((((Drehzahl/60)/MessInterval)/1000)*500) oder .equ DrehzahlFaktor = Q15((((Drehzahl/60)/MessInterval)/1000)*500) Das ergibt Werte, wie sie bei FMULxx verwendet werden. Also im Bereich -1<x<+1. MfG Spess
> Was kann ich tun?
Der Preprozessor arbeitet mit 32-Bit-Ganzzahlen. Man sollte also die
Konstanten ganzzahlig halten. Mit Festkommaarithmetik kommt man oft zum
selben Ergebnis.
Hi Nachtrag: >denn das eigentliche Problem ist, das der AVR Asembler mir bei >der Konstante "MessInterval" die 1 hinter dem komma abschneidet. Das >erzeugt dann natürlich die Fehlermeldung das nicht durch 0 geteilt >werden kann. Dann nehm doch: .equ DrehzahlFaktor = 1/(((Drehzahl/60)/MessInterval)...) mit einer ensprechenden Skalierung 2^n und mache eine Multiplikation. MfG Spess
Das Probem Ganzzahlrechnung wird sich in allen deinen Berechnungen zeigen. Gib doch MessInterval in Millisekunden statt in s an, d.h. verrechne es mit dem Faktor 1000 Ich würde die Formel auch umstellen insbesondere die Multiplikation mit 500 am Anfang statt am Schluss machen. .equ DrehzahlFaktor = (Drehzahl * 500) / (60 * ms_MessInterval)
Oberlehrermodus á la Falk B.: Du suchst eigentlich http://www.mikrocontroller.net/articles/Festkommaarithmetik
Also irgendwie ist mir das ganze noch immer Schleierhaft. Mit folgender Schreibweise hat es jetzt Funktioniert: .equ Drehzahl = 100 ; Umdrehungen pro Minute .equ MessInterval = 10 ; in Millisekunden .equ DrehzahlFaktor = ((Drehzahl/60)*500)/(1000/MessInterval) .equ CPUFrequenz = 8000000 .equ PWMFrequenz = CPUFrequenz/256 Während es mit folgender Schreibweise nicht funktionierte: MessIntervall = 10 ; in Millisekunden .equ DrehzahlFaktor = ((Drehzahl/60))/(1000/MessInterval)*500 In dem Fall wurde zwar keine Fehlermeldung produziert, aber die Konstante DrehzahlFaktor hat einfach den Wert 0. Ich stehe aber schon wieder vor dem nächsten Problem: Ich brauche für einen P Regler einen Verstärkungsfaktor zwischen 1 und 2. Das heißt ich muss mit einer Kommazahl Multiplizieren. Das gedachte Komma ist nach dem 6. Bit. Das heißt: 00,000000 Der Multiplikator wird dann nach dem bekannten Verfahren um 6 stellen nach links verschoben, multipliziert und wieder zurückgeschoben. Ich möchte den Wert für den Verstärkungsfaktor wieder per .equ Befehl vom Assembler errechnen lassen. Nur der kann ja nicht mit Kommazahlen umgehen und erst recht nicht mit welchen die ihre komastelle nach dem 6. bit haben. Hat jemand ne Idee?
Иван S. schrieb: > Oberlehrermodus á la Falk B.: > Du suchst eigentlich > http://www.mikrocontroller.net/articles/Festkommaarithmetik Nein, das sucht er eigentlich nicht. Das Prinzip ist zwar dasselbe, ihm geht es aber um den Preprozessor des AVR-Studios (also um Rechnen auf dem PC), während der Artikel vom Rechnen auf dem AVR ausgeht. Das sind zwei völlig verschiedene Baustellen.
Steffen P. schrieb: > Mit folgender Schreibweise hat es jetzt Funktioniert: Scheinbar... > .equ Drehzahl = 100 ; Umdrehungen pro Minute > .equ MessInterval = 10 ; in Millisekunden > .equ DrehzahlFaktor = ((Drehzahl/60)*500)/(1000/MessInterval) > > Während es mit folgender Schreibweise nicht funktionierte: > .equ Drehzahl = 100 ; Umdrehungen pro Minute > .equ MessInterval = 10 ; in Millisekunden > .equ DrehzahlFaktor = ((Drehzahl/60))/(1000/MessInterval)*500 > > In dem Fall wurde zwar keine Fehlermeldung produziert, aber die > Konstante DrehzahlFaktor hat einfach den Wert 0. Fliesskommaergebnis: (100/60)*500/(1000/10) = 8,33 Fall 1: Teilausdruck 1a: 100/60 = 1,67 Ganzzahl: 1 *500 = 500 Teilausdruck 1b: 1000/10 = 100 Gesamtausdruck 1: 500 / 100 = 5 Fehler: -40% Fall 2: Teilausdruck 2a: 100/60 = 1,67 Ganzzahl: 1 Teilausdruck 2b: 1000/10 = 100 Gesamtausdruck 2: 1 / 100 = 0,01 Ganzzahl: 0 * 500 = 0 Fehler: -100% Multipliziere früh mit 500 Beitrag "Re: AVR Studio, Rechnen mit Fließkommazahlen" .equ DrehzahlFaktor = ((Drehzahl*500)/60)/(1000/MessInterval) Fall 3: Teilausdruck 3a: 100 * 500 = 50000 50000/60 = 833,33 Ganzzahl: 833 Teilausdruck 3b: 1000/10 = 100 Gesamtausdruck 3: 833 / 100 = 8,33 Ganzzahl: 8 Fehler: -4%
Steffen P. schrieb: > Also irgendwie ist mir das ganze noch immer Schleierhaft. Weil du in guter alter Mathemanier davon ausgehst, dass dir auch bei Zwischenergebnissen alle Kommastellen erhalten bleiben. Besonders bei Divisionen ist das aber fatal, denn: Es gibt keine Kommastellen. Weder im Endergebnis noch in den Zwischenergebnissen. 5 / 8 ergibt nun mal 0 und 5 / 8 * 100 ergibt immer noch 0, denn 0 * 100 ist 0 aber 5 * 100 / 8 ergibt 62, denn 500 / 8 ergibt 62 Fazit: Du willst Divisionen so spät wie möglich machen, weil dir dabei alle Kommastellen des Ergebnisses verlorengehen. Auch dann wenn mit dem Ergebnis der Division noch weiter gerechnet wird.
Hm, okay das ergibt Sinn. Ich frag mich nur, warum das avr studio nicht einfach komazahlen unterstützt. Das würde vieles einfacher machen^^ Nur wie mache ich das jetzt wenn vom Assembler eine Kommazahl ausgerechnet werden soll die dann im programm eingefügt werden soll. Es soll eine Kommazahl mit gedachtem komma nach dem 6. Bit sein. Die rechenroutine ist fertig und funktioniert auch. Da ich den wert aber praktisch ermitteln muss (es handelt sich ja um einen motorregler) muss ich ihn oft ändern und jedesmal neu ausrechnen und eintippen. Es währe viel einfacher wenn ich einfach einen Verstärkungsfaktor in Dezimal mit der .equ direktive eintippen könnte und der assembler mir dann den Wert mit der gedachten kommastelle errechnet und ins Programm einfügt.
Steffen P. schrieb: > Ich frag mich nur, warum das avr studio nicht einfach komazahlen > unterstützt. Das würde vieles einfacher machen^^ Mit welchem Floating Point Schema soll denn gerechnet werden? Auf wieviele Nachkommastellen? Die Thematik 'Floating Point Rechnen' ist wesentlich komplexer als du dir im Moment auch nur vorstellen kannst. Wenn du genaueres wissen willst, empfehle ich dir die Lektüre: http://docs.sun.com/source/806-3568/ncg_goldberg.html Naives Benutzen von Floating Point führt oft zu Problemen, an die man im Vorfeld nicht gedacht hat. > ich ihn oft ändern und jedesmal neu ausrechnen und eintippen. Es währe > viel einfacher wenn ich einfach einen Verstärkungsfaktor in Dezimal mit > der .equ direktive eintippen könnte und der assembler mir dann den Wert > mit der gedachten kommastelle errechnet und ins Programm einfügt. Du musst die Berechnung, die du mit dem Taschenrechner machst, so formulieren, dass dich das Problem nicht beisst. Ja, so ist das nun mal in der Programmierung. Das ist keine Schema F Arbeit.
Hi > Es währe viel einfacher wenn ich einfach einen Verstärkungsfaktor in >Dezimal mit der .equ direktive eintippen könnte und der assembler mir dann > den Wert mit der gedachten kommastelle errechnet und ins Programm einfügt. So sollte es gehen: .equ float = ((INT(2.567))<<6) + ((Q7(FRAC(2.567)))>>1) MfG Spess
Hm, das funktioniert tatsächlich. Aber ich denke der Assembler kann nicht mit kommazahlen umgehen. Wie ist das dann möglich? Gibt es hier ein Tutorial zum Rechnen mit dem Assembler?
Hi >Gibt es hier ein Tutorial zum Rechnen mit dem Assembler? Nicht das ich wüsste. Aber in der AVR-Studio-Hilfe zum Assembler unter 'User's Guide->Expressions' findest die notwendigen Infos. MfG Spess
spess53 schrieb: > Hi > >>Gibt es hier ein Tutorial zum Rechnen mit dem Assembler? > > Nicht das ich wüsste. Aber in der AVR-Studio-Hilfe zum Assembler unter > 'User's Guide->Expressions' findest die notwendigen Infos. Warum suchen viele Leute immer wieder Infos im Netz, die sie bereits auf der eigenen Festplatte haben? > > MfG Spess
Auf die seite in der hilfe bin ich durchaus schon gestoßen. Damit das richtig sitzt ist ein Tutor aber nicht schlecht. Naja, danke für die viele Hilfe! Ihr habt mir gut weitergeholfen.
Hi
>Damit das richtig sitzt ist ein Tutor aber nicht schlecht.
Braucht ihr denn für jeden Sch... ein Tutorial? Einfach mal hinsetzen
und selbst ausprobieren.
MfG Spess
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.