mikrocontroller.net

Forum: Digitale Signalverarbeitung / DSP IIR auf DsPic mit Koeffizient > 1


Autor: Rupert (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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?IdcServic...) 
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?

Autor: die ??? (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

        b_0 + b_1 * z^-1 + b_2 * z^-2
H(z) = -------------------------------
         1 + a_1 * z^-1 + a_2 * z^-2

und anschließend

        b_0 + b_1 * z^-1 + b_2 * z^-2
H(z) = -------------------------------
        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.

Autor: Rupert (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
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.)

Autor: die ??? (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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:

#include "dsp.h"

/* Aufpassen bei der Reihenfolge. Es kommt vor, */
/* dass die Koeffizienten nicht der Reihe nach */
/* abgelegt werden, sondern durcheinander -> Doku */
fractional Coeff[5] = {258, 0,-31028, -258, 15869};

/* OK */
fractional d1[2] = {0,0};

/* OK */
fractional d2[2] = {0,0};

/* OK, _ein_ Sample rein und _ein_ Sample raus */
fractional Source, Dest;

/* Liegen die Koeffizienten in der Data-Code-Sektion? */
IIRTransposedStruct BandPass = {0, Coeff, 0xFF00, d1, d2, 1};

/* Nur einmal aufrufen, niemals im laufenden Betrieb */
IIRTransposedInit (&BandPass);

/* Nicht gut! 16 sollte hier 1 sein, dein Samplearray ist nur 1 tief */
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.

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.