mikrocontroller.net

Forum: Digitale Signalverarbeitung / DSP Koeffizienten an 24 bit Festkommaformat anpassen, Matlab


Autor: Carol W. (carol)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich würde gerne mit Matlab eingelesene Koeffizienten als 24 Bit Zahl 
darstellen.

-1 entspicht $800000 (hex)
1-2^(-23) entspricht $7FFFFF

Die eingelesenen Koeffizienten sehen so aus:
0.001953125

Gibt es eine Möglichkeit mit Matlab die Werte in die entsprechende 
Hexadezimale Darstellung zu wandeln?

mfg

Autor: remote1 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Matlab hat ebenso sprintf...

Autor: Carol W. (carol)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wie würde der Befehl aussehen, der aus 0.9999998808 --> 7FFFFF macht?

Autor: Gerrit Buhe (gbuhe)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Carol,

eigentlich verstehen die Preprozessoren der Assembler/Compiler die 
q23-Zahlen direkt. Bei Deiner Wortbreite von 24 Bit tippe ich auf einen 
Motorola/Freescale DSP56xxx. Auch dort kann man die Koeffizienten 
einfach so angeben:

  dc  -0.0000005734  ;coef1
  dc  0.0000016536  ;coef2
  dc  0.0000003550  ;coef3
  dc  0.0000002282  ;coef4
  dc  0.0000054611  ;coef5
  dc  0.0000015115  ;coef6
  dc  0.0000027512  ;coef7
  dc  0.0000112883  ;coef8
  dc  0.0000017115  ;coef9
  dc  0.0000057759  ;coef10 .....

Ich lasse das immer gleich von Matlab in eine Koeffizienten-Datei 
schreiben, die ich per "include" einbinde.

Wenn Du es dennoch in Matlab auf 2er-Komplement-Darstellung in hex 
bringen möchtest, geht das wie folgt:

numbits=24;
q=quantizer('fix',[numbits 0]);

s_in = -1:0.1:1;                  //floating point
s_dez = s_in * 2^(numbits-1);     //fix point 2er Komplement
s_hex = num2hex(q, s_dez);        //und in hex verwandelt

Viel Erfolg!

Gerrit, DL9GFA

Autor: Carol W. (carol)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Stimmt, DSP56371.
Hatte ich bisher auch so gemacht.
Die Koeffizienten werden alle in ein text file geschrieben.

A=data;
fid=fopen('koeff.txt','wt+');
fprintf(fid,' DC %0.8f\n',A);
fclose(fid)

...
 DC 0.00041151
 DC 0.00018835
 DC -0.00004542
 DC -0.00028038
...

Das Ausgangssignal geht dann aber oft in die Sättigung. Denke das die 
Skalierung der Werte in der DALU nicht stimmt

Autor: Gerrit Buhe (gbuhe)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Carol,

> Das Ausgangssignal geht dann aber oft in die Sättigung. Denke das die
> Skalierung der Werte in der DALU nicht stimmt

wenn Du darauf achtest, daß die Verstärkung eines FIR-Filters 1 bleibt, 
sollte es auch angesichts des großen Akkus von 56 bit kein Problem mit 
Sättigung geben. Bei IIR-Filtern sieht das anders aus. Hier kann es 
schnell Überläufe in den Taps geben, die ja i.d.R. nur in 
24Bit-Speicherzellen abgelegt sind. Um das zu vermeiden, sollte man die 
Ordnung nicht über zwei wählen und ggf. mehrere IIR-Filter zweiter 
Ordnung kaskadieren. Natürlich ist auch eine Erweiterung der 
Tap-Speicher auf doppelte Wortbreite (48 bit) möglich. Falls Du auch bei 
IIR-Filtern zweiter Ordnung Probleme hast, möchte ich Deine 
Aufmerksamkeit auf die Scaling-Modes lenken (siehe Beschreibung SR - 
Status Register), die korrekt eingestellt sein sollten.

Gruß,

Gerrit, DL9GFA

Autor: Carol W. (carol)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mit den Koeffizienten des FIR Filters müsste dann soweit alles richtig 
sein.
Der Fehler könnte bei Ringspeichern liegen.

Zwei Modulo Register(m0,m4) werden mit Anzahl der Koeffizienten - 1 
geladen. Die Register r0,r4 zeigen dann jeweils auf die "Buffer Base 
Address".
  org y:(COEFF_BASE_ADDRESS)
  include "..\Koeff.fir"                   
    
NUM_COEFF equ Anzahl_Koeff

  org X:(SAMPLE_BASE_ADDRESS)     

RX_BUFF_BASE  dsm    Anzahl_Koeff 
 

Wäre das soweit richtig?

Autor: Gerrit Buhe (gbuhe)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Carol,

Deine Zeilen sind soweit korrekt. Ein vollständiges Beispiel von mir, 
ordentlich dokumentiert, findest Du unter folgendem Link:

http://unidsp56.de/downloads.html

--> "Kleine Beispielprogramme" --> "FIR-Filter mit Scilab-Skript..."

Laß Dich nicht irritieren davon, daß ich die Koeffizienten erst im 
p-Speicher ablege und bei der Initialisierung in den x-Speicher kopiere. 
Das ist nötig, wenn Du das Beispielprogramm aus einem Flash-Speicher per 
Boot-Loader holst, der nur P-Speicher kennt. Du kannst die 
include-Anweisung direkt unter x: oder y: so lassen, wenn Du das 
Programm per Debugger lädst.

Viel Erfolg!

Gerrit, DL9GFA

Autor: Carol W. (carol)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke für deine Hilfe. Es funktioniert ...

Die Verstärkung des FIR-Filters ist immer kleiner als 1, wenn alle 
Koeffizienten kleiner als 1 sind?

mfg

Autor: Gerrit Buhe (gbuhe)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Carol,

> Danke für deine Hilfe. Es funktioniert ...

Super!

> Die Verstärkung des FIR-Filters ist immer kleiner als 1, wenn alle
> Koeffizienten kleiner als 1 sind?

Nein, die Verstärkung ist die (vorzeichenbehaftete) Summe aller 
Koeffizienten des FIR-Filters. Wenn Du in das Scilab-Skript meiner 
letzten Referenz schaust, findest Du folgendes zum Design eines 
FIR-Tiefpasses:

lv =-N/2+0.5:N/2;                           // N - number of coeffs
coef=sinc(2*%pi*fc/fs*lv).*window('kr',N,10);   //calculate coeffs, 
apply windowing
coef=coef/sum(coef);                       //normalize to have unity 
gain

Ein Rechteck (idealer Tiefpaß) im Frequenzbereich eintspricht einer 
sin(x)/x = sinc(x) Funktion im Zeitbereich als Impulsantwort. Daher 
werden die Koeffizienten oben als Abtastwerte einer Sinc-Funktion 
ermittelt. Um die Verstärkung des TP-Filters auf 0dB, bzw. 1, zu setzen, 
habe ich die letzte Zeile eingefügt, die alle Koeffizienten durch die 
vorherige Summe aller Koeffizienten teilt. Diese Art der Skalierung der 
Koeffizienten kann man auch nutzen, um von 0dB abweichende Verstärkungen 
im Durchlassbereich einzustellen, z.B. anschließend coef = coef * 2, 
wenn 6dB verstärkt werden soll.

Viele Grüße!

Gerrit, DL9GFA

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.