Koeffizienten an 24 bit Festkommaformat anpassen, Matlab

OP #2066206
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
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
OP
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
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
OP
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".
1
  org y:(COEFF_BASE_ADDRESS)
2
  include "..\Koeff.fir"                   
3
    
4
NUM_COEFF equ Anzahl_Koeff
5

6
  org X:(SAMPLE_BASE_ADDRESS)     
7

8
RX_BUFF_BASE  dsm    Anzahl_Koeff

Wäre das soweit richtig?
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
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

Eine eigene Frage? Dieser Thread ist über 15 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.