Forum: Mikrocontroller und Digitale Elektronik diskr. Tiefpass, bilineare Transformation und Realisierung


von Martin W. (martin_s86)


Lesenswert?

Ich versuche zum ersten mal einen einfachen Tiefpass auf einem 32bit ARM 
Cortex M3 (LPC1766) zu realisieren. Ich erhoffe mir, dass mal jemand 
drüber schaut ob irgendwo logische Fehler sind oder der Code so 
überhaupt richtig lauffähig ist und seine Funktion erfüllt.

Dabei bin ich nach dem Buch "Signalverarbeitung" von Martin Meyer 
vorgegangen.

Dort wird mit der bilinearen Transformation
und der bekannten Übertragungsfunktion eines analogen Tiefpasses
der Frequenzgang möglichst gut angenähert. Man erhält wie im Buch 
beschrieben dann
Die Grenzfrequenz und Abastrate will ich später zum rumspielen 
verändern. Ich substituiere
 und stelle daraus die Differenzengleichung auf

Zurücktransformiert:
Umstellen nach y[n]

Ich habe nun mal etwas Pseudocode erstellt, der diesen Filter 
realisieren soll. Ich habe jedoch noch nicht auf eventuelle Überläufe 
geachtet. Dazu muss ich mir erst noch angucken welche Genauigkeit ich 
bei den Koeffizienten brauche bzw. wie sich diese überhaupt auf den 
Freuquenzgang auswirken.
1
uint16 uiSample = ReadADU();    //12Bit Messwert, Offset bei (2^12)/2 = 2048
2
uiSample = uiSample>>2;    //10Bit DA-Wandler
3
4
int16 iOutput[2];      //letzter[0] und vorletzter[1] Filteroutput (y[n] und y[n-1])
5
6
int8 b[2] = {b0, b1};    //Koeffizienten, Fixkomma mit einer Nachkommastelle, z.B. -0.7 ^= -7
7
int8 a[2] = {a0, a1};    // b0=b1=1, a0=1+tau, a1=1-tau   
8
9
int16 iBuffer[2];      // x[n] und x[n-1]
10
11
//Weiterrücken im Buffer
12
iBuffer[1] = iBuffer[0];
13
14
//Sample einfügen, aber bitte mit Vorzeichen
15
iBuffer[0] = (int16)uiSample;
16
17
//letzter ist nun vorletzter
18
iOutput[1] = iOutput[0];
19
20
21
//Na dann mal los, hoffentlich ohne Überlauf
22
//Nachkommastelle wieder rausrechnen mit Faktor/Divisor 10
23
for (int i = 0; i<2; i++)  //1. Schritt
24
{
25
  iOutput[0] = iOutput[0] + (b[i]*iBuffer[i])/10;
26
}
27
28
iOutput[0] = iOutput[0] - (a[1]*iOutput[1])/10;    //2. Schritt
29
iOutput[0] = (iOutput[0]*10)/a[0];          //3. Schritt
30
31
32
uint16 IchBinGefiltert= (uint16)iOutput[0];    //fertig


Ich habe überlegt ob es nicht sinnvoll wäre den Offset vorher 
rauszurechnen und später wieder drauf zu addieren. Naja erstmal sehen 
was ihr meint.

Gruß

Maddin

von Martin W. (martin_s86)


Lesenswert?

Hm ist mein Beitrag so unwürdig, beantwortet zu werden..? Dabei steckt 
selbst hier mehr Arbeit drin als beim schrottigen Tutorial von diesem 
Andreax...

naja eine Chance habt ihr noch :) hochschieb

Gruß

Maddin

von Alex (Gast)


Lesenswert?

Hallo,

mit diesen rekursiven Filtern kenne ich mich kaum aus - die Mathe dafür 
ist mir zu schwer.
Was ich aber weis ist, dass diese Filter mit Fließpunktarithmetik 
funktionieren (müssen) - Rundungsfehler summieren sich.
Es soll nicht einfach sein, sie stabil zu bekommen. Außerdem können 
leicht Überläufe auftreten.

Wenn du Integer (-Arithmetik) verwenden willst sind FIR-Filter richtig!
Man braucht zwar mehr MAC-Operationen - dafür aber Integer!
Außerdem gibt es einfache Formeln um die Koeffizienten auszurechnen.
Zudem ist der Frequenzgang einfach die FFT der Koeffizienten - und 
umgekehrt!! Die inverse FFT des (beliebigen) gewünschten Frequenzganges 
ergibt die Koeffizienten.

Die Anzahl der Rechenstellen beeinflusst das Rauschen & die maximal 
erreichbare Dämpfung.

>> Hm ist mein Beitrag so unwürdig, beantwortet zu werden..?
Nein! aber das Thema Digitalfilter ist speziell & sehr anspruchsvoll.
Wenige kennen sich aus, und die meisten davon (schätze ich) benutzen 
Hilfsprogramme / -Module wie Mathlab.

Alex

von Never_Knows_Nothing (Gast)


Lesenswert?

wenn es um simple zweckmäßige filter geht kann ich auch nur FIR filter 
empfehlen. Wenn es was komplexeres sein sollte, wie rekursive filter, 
erstmal in Matlab simulieren und die Stabilität prüfen bevor man es in 
Fix-Komma auf nem controller implementiert. Bist doch student, da sollte 
matlab ja kein problem darstellen ;-)

Simulik rauschquelle + eigenen Funktionsblock mit deinem Filter und ne 
FFT hintendran.
Matlab besitzt auch Funktionblöcke um das ganze in Fixkomma zu machen, 
allerdings hat mein Matlab das Blockset nicht. aber mal nachschaun kost 
ja nix

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
Noch kein Account? Hier anmelden.