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
Wie würde der Befehl aussehen, der aus 0.9999998808 --> 7FFFFF macht?
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
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
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
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
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
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.