Hallo, ich habe ein Problem mit, wie im Titel schon erwähnt, mit Fikommazahlen. Ich verwende das Luminary LMS38962 Microcontroller Board von TI. Dabei verwende ich die miteglieferte DriverLib. In dieser ist eine Funktion für den Sinus definiert. Allerdings wird für die Berechnung dieser ein Fixkommawert des Datentyps unsigned long benötigt (0.32). Dieser gibt den Winkel in Prozent an, also 2*pi = 100% = 0.999999999... Soviel ich aber weiß (vielleicht ist dieses vermeintliche Wissen falsch) werden die Werte aber als Gleitkomma (also mit Mantisse und Exponent) abgespeichert. Leider bin ich nicht in der Lage den Gleitkommawert in einen Fixkommawert umzuwandeln, oder direkt einen solchen zu erzeugen (wär noch viel besser). Habe schon die ganze Allwissende Müllhalde abgeklappert, jedoch ohne Erfolg. Ich hoffe ihr könnt mir weiterhhelfen. mfg Graph Oszillo
Graph Oszillo schrieb: > Leider bin ich nicht in der Lage den Gleitkommawert in einen > Fixkommawert umzuwandeln Woran scheitert es denn? Auf einem µC ist es oft vorteilhaft Fixkommazahlen auf Basis vom 2er-System zu verwenden. Welche Auflösung brauchst du für deine Fixkommazahlen?
Uh, Ernsthaft? Also, nehmen wir mal das Dezimalsystem. Was ergibt sich aus: 0,09 + 0,01? Und nun mal das Hexadezimalsystem. Was ergibt sich aus: 0x0F + 0x01? Da der Wertbereich deiner Angabe nach sich auf 0,0 - 0,999~ erstreckt, sagen wir mal bis 1,0, und Du nun 32 Bit hast... Wenn die 32 Bit nun die Nachkommastellen angeben, so ist das 0xFFFFFFFF was dann 0.999~ entsprechen soll. Dieser Hex-Wert entspricht dezimal 4.294.967.295. Die 1,0 wäre dann 4.294.967.296 oder in Hex 100000000. Klickt es nun? Anders ausgedrückt: Du dividierst den Fixed-Point von "0,32" Bit ganz einfach durch 4.294.967.296 um einen Fließkommawert im Bereich 0,0 - 0,999~ zu erhalten. Wenn Du aber den Wertbereich 0,0 - 1,0 haben willst, dann dividierst Du ganz einfach durch 4.294.967.295. Grüße, Chris Edit: Oder wenn Du den 32-Bit Fixed-Point Wert haben willst dann dividierst Du die 4.294.967.296 oder 4,294,967,295 einfach durch den Fließkommawert (der den Bereich 0,0 bis 0,999~ oder 1,0 haben muss).
Das ist genau das Gleiche wie beim Ergebnis eines AD-Wandlers. Da ist die Zahl nur nicht so groß. 10-Bit-ADC skaliert auf Uref: U = Uref * ADC_Value / 2^10 (=1024) Dein Sinus skaliert auf 1: sin = (1 * )Value / 2^32 (= s.o.) Oder auf 255 zur Ausgabe auf einen 8-Bit DA-Wandler DA-Value = 255 * Value / 2^32 mfg.
Wieso braucht man eigentlich eine Tabelle mit dem Typ unsigned long, wenn man Zahlen aus dem Bereich 0,000 .. 0,999 - also drei Stellen im Dezimalsystem - als Fixkommawerte ablegen möchte. Um die Zahlen darzustellen, reichen 10-Bit, d.h. 22-Bit sind völlig nutzlos. Welche Genauigkeit muß denn die Tabelle nun wirklich haben, d.h. wie sauber muß der Sinus sein?
Werner schrieb: > Welche Genauigkeit muß denn die Tabelle nun wirklich haben, d.h. wie > sauber muß der Sinus sein? So sauber wie möglich. Also unendlich viele Werte. Wie bei Analog. Das geht aber digital nicht. Das ist immer endlich. Also rechnet man auf einem 32-Bit-Rechner auch mit 32 Bit. Damit rechnet er sowieso. Und zwar solange wie möglich. Das Umrechnen in eine Dezimalzahl ist erst der letzte Schritt und nur für uns. Rechnen kann der Controller besser binär. Und die Rundungsfehler bleiben bei 32 Bit klein. Auf einem 8-Bitter, wo das zum zeitaufwendigen K(r)ampf wird, überlegt man sich, ob man so viele Werte wirklich braucht, wenn man sie z.B. auf einen 10-Bit DAC ausgeben will. mfg.
Thomas Eckmann schrieb: > Auf einem 8-Bitter, wo das zum zeitaufwendigen K(r)ampf wird, überlegt > man sich, ob man so viele Werte wirklich braucht, wenn man sie z.B. auf > einen 10-Bit DAC ausgeben will. > > mfg. Wobei man auch da beachten muss das es in gewissen Situationen ein paar gute Tricks gibt. Viele µC haben einen Hardware-Multiplier, also eine Einheit die in meistens einem Takt eine Multiplikation machen kann. Damit kann man aber auch auch eine Division machen. Natürlich nur unter gewissen Bedingungen. Grüße, Chris
Werner schrieb: > Wieso braucht man eigentlich eine Tabelle mit dem Typ unsigned long, > wenn man Zahlen aus dem Bereich 0,000 .. 0,999 - also drei Stellen im > Dezimalsystem - als Fixkommawerte ablegen möchte. Um die Zahlen > darzustellen, reichen 10-Bit, d.h. 22-Bit sind völlig nutzlos. > > Welche Genauigkeit muß denn die Tabelle nun wirklich haben, d.h. wie > sauber muß der Sinus sein? Falls Du dich damit auf mein Beispiel beziehst dann beachte bitte das ich nicht drei Nachkommastellen angegeben habe, sondern z.B. 0,999~, wobei das ~ dann "unendlich" repräsentiert. Grüße, Chris
Thomas Eckmann schrieb: > So sauber wie möglich. Also unendlich viele Werte. Wie bei Analog. "So sauber wie möglich" kann kein Mensch bezahlen und ist meistens nicht wirklich nötig. Was hat die Sauberkeit des Sinus mit "Analog" und "unendlich viele Werte" zu tun. Als Kriterium würde man eher sowas wie SNR oder Dämpfung der Oberwellen erwarten. Aber vielleicht kann sich unser Graph mal zu seinem Problem äußern.
Vielen Dank an alle! Von mir aus müsste der Wert nicht mal auf drei Nachkommastellen genau sein, da ich diesen nur auf dem 128x96 Pixel großen Display zeichnen werde. Allerdings rechnet diese Sinusfunktion sowieso keine Werte selbst aus. Sie hat die Werte eines viertel Sinus (90°) in einem Array als 0.16 Fixpoint unsigned short gespeichert, und legt diese Kurve mehrmals aneinander. Ausgegeben wird ein 16.16 Fixpoint Long. Bezüglich der Umwandlung hätte ich noch eine Frage: Wenn ich einen 16.16 Fixpoint wieder auf Floatingpoint umwandeln will, muss ich dann einfach durch 2^16 dividieren?
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.