Ich bin dabei einen IIR-Filter zweiter Ordnung auf einem dsPIC 30F6010 zu programmieren und würde dabei gerne das von Microchip programmierte Beispiel CE001 (http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&nodeId=2620) benutzen. Die IIRTransposed-Funktion benötigt dabei die 5 Filter-Koeffizienten ({b0, b1, a1, b2,a2}) in Fractional-1.15. Da a1 aber -1.8937941 ist, müsste ich theoretisch durch 2 dividieren. Nur verbietet sich mir das, weil dabei ja auch a0 durch zwei dividiert würde und folglich die Funktion von einem falschen a0 ausgehen würde (immer noch 1 statt neu 0.5). Weiss da jemand, wie ich da vorgehen muss?
Du kannst den Filter getrost mit Koeffizienten füttern die skaliert sind. Das drückt sich lediglich in einem Verstärkungsfaktor aus. Die '1' (a_0) steht im zeitdiskreten Bereich schließlich für den Koeffizienten des "Ausgangs" y_k - ob dieser "Ausgang" nun auf 1 oder 0.5 bezogen wird ist egal. Mach dir den Spaß und transformiere
1 | b_0 + b_1 * z^-1 + b_2 * z^-2 |
2 | H(z) = ------------------------------- |
3 | 1 + a_1 * z^-1 + a_2 * z^-2 |
und anschließend
1 | b_0 + b_1 * z^-1 + b_2 * z^-2 |
2 | H(z) = ------------------------------- |
3 | 0.5 + a_1 * z^-1 + a_2 * z^-2 |
in den zeitdiskreten Bereich und bilde die Differenzengleichung, so sieht man es imho am besten.
Vielen Dank schon mal. Leider verstehe ich es trotzdem noch nicht so ganz. Da a0 ja der Koeffizient für den Ausgang ist, soll ich dann folglich am Schluss noch durch 2 dividieren (resp. shift rechts um 1 bit)? Konkret: IRTransposedStruct-Type hat ja da als letztes Argument "int finalShift". Kommt da also eine 1 rein? Zudem tue ich mich echt schwer, das oben verlinkte Beispiel (und auch die darin vorkommende Funktionen) zu verstehen. Ich habe deshalb mal auf eigene Faust versucht, die Funktionen anzuwenden. Wäre schön, wenn sich das mal jemand anschauen könnte. Denn funktionieren tut es (wie erwartet) leider nicht. Die Beschreibung der Funktionen findet man unter "5.15 IIRTransposed" in der angehängten Datei. #include "dsp.h" [...] fractional Coeff[5] = {258, 0,-31028, -258, 15869}; fractional d1[2] = {0,0}; fractional d2[2] = {0,0}; fractional Source, Dest; IIRTransposedStruct BandPass = {0, Coeff, 0xFF00, d1, d2, 1}; [...] IIRTransposedInit (&BandPass); fractional test = *IIRTransposed (16, &Source, &Dest, &BandPass); Ich muss ehrlich eingestehen, dass ich nicht wirklich viel verstehe. Weder was es mit diesem X-Data / Y-Data auf sich hat, noch was unter numSamps (1. Argument für IIRTransposed) verstanden wird (ich habe 16 eingegeben, weil im Beispiel von Microchip 256 steht, wobei dort irgendwie alle 16 16-bit A/D Result Buffer verwendet werden (ich brauche deren nur einen). Wäre wirklich super, wenn da jemand was Konstruktives dazu schreiben könnte, denn ich bin arg am verzweifeln (Die Uhr tickt.)
Rupert wrote: > soll ich dann folglich am Schluss noch durch 2 dividieren (resp. shift > rechts um 1 bit)? Nein, du verstärkst zum Schluss wieder. Links-Shift. > IRTransposedStruct-Type hat ja da als letztes Argument "int finalShift". > Kommt da also eine 1 rein? Wenn du vorher mit 1/2 normiert hast dann macht es natürlich Sinn den "Ausgang" am Ende wieder mit 2 zu denormieren - ergo finalShift = 1. Zum probieren geht auch 0, die Werte sind dann entsprechend kleiner. > Ich habe deshalb mal auf eigene Faust versucht, die Funktionen anzuwenden. Das ist gut. Ein paar Gedanken:
1 | #include "dsp.h" |
2 | |
3 | /* Aufpassen bei der Reihenfolge. Es kommt vor, */
|
4 | /* dass die Koeffizienten nicht der Reihe nach */
|
5 | /* abgelegt werden, sondern durcheinander -> Doku */
|
6 | fractional Coeff[5] = {258, 0,-31028, -258, 15869}; |
7 | |
8 | /* OK */
|
9 | fractional d1[2] = {0,0}; |
10 | |
11 | /* OK */
|
12 | fractional d2[2] = {0,0}; |
13 | |
14 | /* OK, _ein_ Sample rein und _ein_ Sample raus */
|
15 | fractional Source, Dest; |
16 | |
17 | /* Liegen die Koeffizienten in der Data-Code-Sektion? */
|
18 | IIRTransposedStruct BandPass = {0, Coeff, 0xFF00, d1, d2, 1}; |
19 | |
20 | /* Nur einmal aufrufen, niemals im laufenden Betrieb */
|
21 | IIRTransposedInit (&BandPass); |
22 | |
23 | /* Nicht gut! 16 sollte hier 1 sein, dein Samplearray ist nur 1 tief */
|
24 | fractional test = *IIRTransposed (16, &Source, &Dest, &BandPass); |
> Ich muss ehrlich eingestehen, dass ich nicht wirklich viel verstehe. > Weder was es mit diesem X-Data / Y-Data auf sich hat Ich kenne den DSPic nicht, aber wie es mir scheint sind X-Data/Y-Data Speicherbereiche die per Code-Page-Schalter eingestellt werden können. Die Koeffizienten dürfen im X-Data-Bereich oder im Programmspeicher abgelegt sein (daher der Wert coeffsPage). Die Delaylines dürfen ausschließlich im Y-Data-Bereich abgelegt werden.
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.