mikrocontroller.net

Forum: Digitale Signalverarbeitung / DSP DSP Normalisierung Float und Konvertierung Fixed Point


Autor: Matthias G. (gille)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen,

Ich bin recht neu bei der DSP-Programmierung und habe ein vermutlich 
sehr einfaches Problem:

Ich programmiere in C und will später mit einem STM32Disco mit 16Bit ADC 
arbeiten. Momentan beschäftige mich gerade mit Festkommaarithmetik.

Zum Probieren habe ich zunächst ein float array welches ich mittels 
Schleife und Sinusfunktion fülle.

Das ganze will ich dann normieren indem ich jeden Wert durch den 
Betragsmäßig größten Teile.

Ist der größte Betrag positiv bekomme ich dann als größten Wert eine 1. 
Nun ist es ja aber so dass das fractional Format 1.15 von 
-1<...0.999999... geht und nicht bis +1. Wobei das erste Bit ja das 
Vorzeichen repräsentiert und der Rest die Nachkommastellen 1/2, 1/4 usw.

Wenn ich also diese float-Werte in short konvertiere bekomme ich für den 
Spitzenwert statt 32767 (0b0111 1111 1111 1111)den Wert -32768 (0b1000 
0000 0000 0000).

Es ist mir auf Bit-Ebene klar wieso das passiert, da ich ja 
(short)(1.0*(1<<15)) rechne.

Deshalb meine Fragen:
Muss ich was bei der Normierung ändern um der Definition des Fractional 
Formats gerecht zu werden?
Wie wäre das "Lehrbuchgerechte" vorgehen bei einer solchen 
Konvertierung?

Danke.
Gruß Gille

Autor: Martin O. (ossi-2)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Eine Möglichkeit wäre, die Werte quasi vorher mit 32767/32768 zu 
multiplizieren, damit alle Werte ins 1.15 Format passen. Oder Du 
"rundest" die 1.0 zi 0.111111111111111111111111 mit kleinem Fehler.

Autor: Matthias G. (gille)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ok, Danke.

Das machst Sinn bei meinem Problem. Wenn ich aber später echtzeitfähig 
arbeite kann ich mir doch sicher keine Mutiplikation und anschließende 
Division jedes einzelnen Wertes leisten oder?

Der ADC wird mir ja sicher schon short-Werte mit Offset raus geben (0 
=-1V und 65535=+1V oder so). Damit kann ich ja dann direkt arbeiten.

Wenn ich allerdings einen Datenstrom bekomme der float-Werte enthält 
komme ich doch sicher schnell an die Grenze der Geschwindigkeit, weil 
der DSP ja eben keine Gleitkommaarithmetik beherrscht bzw nur langsam.

Deshalb ist ja die Idee so schnell wie möglich auf fixed point zu 
wechseln und die Rechnerei dann damit zu machen.

Oder hab Ich da grundlegend was falsch verstanden?

Autor: Walter T. (nicolas)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Matthias G. schrieb:
> STM32Disco

Welches? Die M4 sind erstaunlich schnell bei Float32. Ich habe gestern 
für Spaß einen recht multiplikationslastigen Algorithmus erst in float 
und dann in Festkomma umgestellt, und erstaunt festgestellt, daß es 
praktisch keinen Unterschied in der Laufzeit gab.

Bei 16-Bit-Festkomma-Zahlen sollte das etwas anders aussehen, weil kein 
64-Bit-Zwischenergebnis bei Multiplikationen notwendig ist. Aber der 
Unterschied bleibt mittlerweile erstaunlich klein.

Autor: Mampf F. (mampf) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Matthias G. schrieb:
> Ich programmiere in C und will später mit einem STM32Disco mit 16Bit ADC
> arbeiten. Momentan beschäftige mich gerade mit Festkommaarithmetik.

Wenn das ein STM32Disco mit Cortex M4 zB ist, brauchst du bezüglich 
Festkommaarithmetik nichts machen ... Das wäre langsamer als gleich die 
eingebaute FPU zu verwenden.

Die meisten FPU-Befehle brauchen nur 1 Taktzyklus - außer Division 
(glaube 12 oder 13) und noch ein anderer ... Aber Multiplikation, 
Addition usw alles nur 1 Takt.

Hatte vor kurzem einen Dynamik-Kompressor auf Festpunkt umgebaut und war 
erstaunt, dass der dann langsamer war als alles einfach auf Float zu 
lassen.

: Bearbeitet durch User
Autor: Detlef _. (detlef_a)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja, schließe mich Ossi-2 an. Du normierst auf 32767 bis -32767, also 
2^15-1 bis -(2^15-1). Die Interpretation als 1.15 ist in Matlab Notation
von sum(2.^(-15:-1)) bis -sum(2.^(-15:-1)), mit

sum(2.^(-15:-1))=0.999969482421875=1-2^(-15)

Bei int16_t ist es lästig, dass der größte Wert 32767 und der kleinste 
-32768 ist, also 'unsymmetrisch'. Muss aber so sein, weil es ja eine 
gerade Anzahl Zahlen in int16_t gibt und die 0 auf noch beigehört ;))))

Und richtig ist auch, dass fixed point bei den Cortexen mit FPU keinen 
Sinn mehr macht.

math rulez!
Cheers
Detlef

: Bearbeitet durch User
Autor: Mampf F. (mampf) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nachtrag:

Leider darf ich den Link nicht posten, weil die 
oberschlaue-Foren-Software meint, das wäre Spam (.cn im Link).

Hier steht noch mehr zur FPU:

AN4044
Application note
Floating point unit demonstration on STM32 microcontrollers

Autor: Matthias G. (gille)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ok, vielen Dank.

Ich werde das mal umsetzen und schauen wie mein Professor das so findet 
:)

Autor: --- (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
"Richtige" Festkomma-DSPs haben gegenüber den Registern mehr Bits
in ihren Akkumulatoren und können daher nicht so einfach überlaufen
oder sättigen.
Skalieren/Normalisieren tut man da häufig nur am Ende eines
Berechnungsalgorhitmus, wenn überhaupt.
Nebenbei können typische "richtige" DSP auch parallel noch
die nötigen Adreßoperationen für den Zugriff auf Daten und
Koeffizienten durchführen.

Das "ARMe" einiges an DSP-typischen Operationen anbieten,
was bei der Umsetzung hilfreich ist, sollte nicht darüber
hinwegtäuschen, dass sie eben doch keine "richtigen" DSPs sind.

Und, um die jeweiligen Stärken eines DSPs zu nutzen, wird
man auch heute noch auf Assembler zurückgreifen (müssen).

Tut mir ja leid für dich, aber auch mit einem M4-ARM steigst
du nicht in die typische Programmierung von DSPs ein.
Du kratzt allenfalls ein wenig an deren Algorithmen herum...

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.