Hallo DSP profis ;-) hab eine kleine frag und zwar: ich möchte ein einfaches FIR filter mit matlab (fdatool) designen und später dann in einem dsPIc laufen lassen. ich habe mit dem fdatool die koeffizienten generiert (sind mindestens im bereich von ca -1.0000 bis +1.0000). da ich später dann im dsPIC die koeffizienten als signed int abspeichern und auch die filterschleife mit integer rechnen möchte, hab ich mir gedacht ich multiplizier die koeffitienen mit 2^15, somit befinden sie sich dann im bereich von -32767 bis +32767. das eingangssignal kommt vom 12bit ADC. meine frage nun: wie muss ich die filter routine anpassen, damit das gefilterte ausgangssignal wieder auf einem 12bit DAC ausgegeben werden kann. hier meine bisherige filterroutene für Matlab: ... f0=1000; f1=3000; fa=8000; %Abtastfrequenz n=[0:1/fa:(N-1)/fa]; %Abtastvariable für abgetastetes Signal s=sin(2*pi*f0*n)+cos(2*pi*f1*n); %Signal abtasten %FIR-Filter ord=length(coef)-1; for i=1:length(s), sum=0; for j=1:ord, if i>ord sum=sum+s(i-j)*coef(j); end end y(i)=sum; end ... ich hab auch schon gesehen, dass das fdatool die koeffitienten als signed int als header datei exporteren kann, so kann man diese dann gleich mit einbinden. wäre toll, wenn mir jemand helfen kann. - Danke schon mal, MAX
Hi, einige Punkte: ....... so wäre weniger aufwendig. for i=ord+1:length(s), sum=0; for j=1:ord, sum=sum+s(i-j)*coef(j); end y(i-ord)=sum; end Vorsicht bei Migration von Matlab zu C. Bei Matlab starten Indizes bei 1, in C bei 0. ...... Die Skalierung Deiner Koeffizienten und die Skalierung auf den ADC hängt mit Deiner Rechendynamik zusammen. Angenommen : Deine Koeffizienten sind skaliert mit signed 16Bit, also -32768...32767, brauchse 16Bit Die Eingangswerte haben 12Bit , brauchse zusammen 28Bit Dein Filter macht 40dB Verstärkung für eine Frequenz, Faktor 100, sind nochmal 7Bit, brauchse zusammen 35Bit (Schlecht für 32 Bit Rechnung, Koeffizienten dann grober skalieren). Um die auf dem 12Bit DAC auszugeben mußte dann um 23 Bit shiften. Vorsicht auch bei Zwischenergebnissen der Summe (sum=sum+s(i-j)*coef(j);), da kann es zu filterinternen Überläufen kommen. Vorher alles gut in integer aufm PC checken. Cheers Detlef
Hi Detlef, erstmal danke für die antwort! also seh ich das dann richtig so: meine summe muss immer mindestens 12bit (ADC) + 16bit (koeffizienten) = 28bit sein, jedoch wie kommst du auf die 40dB für eine Frequenz vom Filter. - kannst du das bitte genauer erklären? ... ich hab mal wo gelesen, dass die Summe aller koeffizienten die Versärkung ist, aber hat das nichts mit dem zu tun? ich denke mal, dass sum long und somit 32bit sein soll. was fürdest du sagen was ist die niedrigste auflösung für die koeffizienten in bits ist, damit das ergebnis noch passabel ist? - hab leider noch überhaupt keine ahnung wie das dann in der praxis aussieht ;-)? sum+=sum+s(i-j)*coef(j); müsste auf gehn oder meinst du eher nicht? werd morgen mal das ganze in C auf dem PC etwas testen.. mal sehn. wie würdest du die tiefpässe am ein- und ausgang für fa/2 realisieren? werden in der praxis aktive filter mit OPs verwendet? wenn ja wievielter odernung? - am liebsten wär mir ja ne schaltung mit berechnungsformel zur dimensionierung ;-) ... so wie im tietze schenk. Danke noch mal für die hilfe, gruß, MAX
Hi, 40dB ist Faktor 100. Kenne die Anzahl Deiner Koeffizienten nich ('ord'), aber angenommen, die ist 100, alle Koeffizienten sind =1 (Mittelwertfilter) und Du schiebst immer Einsen rein (Gleichspannung), dann kommt nach ner Weile immer 100 raus, also zusätzliche 7 Bit. Wenn Du dann mit 12 Bit ADC-Daten reingehst und die Summe mit 32 Bit rechnest bleiben noch 13Bit (naja, nimm lieber 12) für die Quantisierung der Koeffizienten übrig. fa/2 Filter: Das ist schwierig zu sagen, ohne Details zu kennen. Cheers Detlef
Hallo, so jetzt hab i's super verstanden, danke! ok hier ein paar details, wobei die nicht 100% sicher sind, denn ich will ja nur die grundsätzliche funktion von einem FIR testen. ein bsp.: FIR filter, Hanning Fenster Ordnung = 51 fa=8000Hz und der ein- und gangstiefpass soll nun auf 4000 Hz bandbegrenzen. und muss nicht extrem steil sein. wenn der übergangsbereich von ca. 3800 bis 4100Hz geht ist das schon ok, denk ich. gruß, MAX
Hi, hört sich nach Audio an. Frequenzanteile jenseits von fa/2 siehst Du gespiegelt um fa/2, 5kHz am Eingang bei fa/2=4kHz kommen als 3kHz an. Hört sich dann eventuell schlecht an, kann man aber recht einfach mit z.B. Matlab mal ausprobieren. Ich weiß aber, daß das Ohr tolerant ist und glaube, daß ne leichte Filterung ausreichen könnte, würde ich einfach mal mit nem passiven Tiefpaß probieren. Cheers Detlef
Hallo, hab mir grad mal denn inneren aufbau des dsPICs angesehn und gesehen, dass die MAC einheit einen 40bit accumulator und einen 40bit barrel-shifter hat, kann ich in diesem fall sie koeffizienten und die anzahl der bits des ADCs erhöhen? - bzw. auf wieviel kann ich die maximal dimensionieren? schöne grüße, MAX
Hi, 12 Bit vom ADC, 16 von Deinen skalierten Coeffs und 6 für die 51er Anzahl, macht 34, da sollten 40 reichen. 22 mal rechtsschieben und Du hast die 12 Bit Eingangsdaten für den DAC. Cheers Detlef
Hallo, bei mir ist gerade die frage aufgekommen, ob es sinnvoll ist den ADC zum bsp mit 10bit und den DAC mit 12bit oder sogar 16bit zu skalieren? wird das ergebnis dadurch besser als nur mit einem 10bit DAC? MAx
Hi, augewogenes Verhältnis zwischen ADC und DAC macht Sinn, bei 10Bit rein und 12Bit raus sind die 2 Bit ja geraten (bei gleichen Abtastraten). Klar issn 16Bit DAC besser als ein 10Bit DAC, aber wenn die unteren 6 Bit Rauschen sind, bringt das nix. Lieber genau rein (12Bit) und genau raus (12Bit). Cheers Detlef
Hallo, ich poste hier mal mein designetes filter. wird eigentlich beim C30 compiler, die mac einheit automatisch verwendet, oder muss ich die filter kern routine in assembler programmieren? MAX
Hi, ich kenne c30 und dsPIC nicht, vermute aber, daß normales C die 40Bit MAC-Einheit nicht nutzen kann aber daß es von C aus eine einfache Routine gibt, um da ranzukommen. Du sprachst oben von fa=8KHz, das Ding im .jpg ist für fa=16kHz ausgelegt!? Die Grenzfrequenz Deines Filters liegt für fa=8kHz ja unter 1kHz, da kannst Du Deinen anti-aliasing Eingangstiefpaß tiefer legen, z.B. auf ne Grenzfrequnz von 1kHz. Die Koeffizienten sind symmetrisch, damit kannst Du Dir die Hälfte der Multiplikationen sparen. Cheers Detlef
ja stimmt, normalerweiße kann ich auch 8khz abtastfrequenz verwenden, abe nur etwas herumgespielt. wie meinst du das mit dem multiplikationen sparen? meinst du es in etwa so: for i=1:length(s), sum=0; for j=1:ord/2, sum=sum+2*s(i-j)*coef(j); end y(i)=sum; end oder hab ich das was falsch verstanden? danke für die hilfe und gruß, MAX
Hi, nee, Du kannst natürlich nicht die Hälfte der Koeffizienten weglassen und dafür mal 2 nehmen! Bei der rohen Rechnung mit symmetrischen Koeffizienten multipliziert Du jeden Abtastwert zweimal mit demgleichen Koeffizienten. Das machts Du bei der Sparversion nicht, sondern speicherst Dir die Teilergebnisse ab. C-Code hab ich momentan dafür nich auf Tasche, angehängtes Strukturbild zeigt aber den Umbau von der Roh- auf die Sparversion für 5te Ordnung. BTW: Matlab ohne 'for' is besser! Dein Codesegment sum=0; for j=1:ord, sum=sum+s(i-j)*coef(j); end y(i-ord)=sum; läßt ich eindampfen auf: y(i-ord)=s(i-j:i-j+ord-1)*coef(j)'; (angenommen, daß s und coef 'liegende' Vektoren sind , also nur eine Zeile und mehrere Spalten haben). Die brutalstmögliche Sparversion ist das eingebaute 'filter' von Matlab: y=filter(coef,1,s); fettich Cheers Detlef
danke detlef! werd mir mal überlegen, wie ich das dann einfach in C implementieren kann. MAX
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.