Forum: Compiler & IDEs TAS3002 Filterkoeffizienten


von Sebastian (Gast)


Lesenswert?

Hallo,

Habe ein Problem mit dem TAS3002.
Hardwaremäßig funktioniert alles, ist auch über I2C ansprechbar und tut 
das was er soll, allerdings komme ich mit den Filterkoeffizienten nicht 
ganz klar.
Für die Berechnung der Koeffizienten habe ich folgende Formeln gefunden:

b0 = 1+((1+alpha)*H/2)
b1 = d*(1-alpha)
b2 = (-alpha-((1+alpha)*H/2))
a1 = b1
a2 = -alpha

where:
alpha = (tan(wc/2Q)-Gf)/(tan(wc/2Q)+Gf) for Gf<1, OR
alpha = (tan(wc/2Q)-1)/(tan(wc/2Q)+1) for Gf>=1
H = Gf-1
d = -cos(wc)
Gf = 10^(G/20) (Gain Factor, linear)
wc = 2*Pi*fc/fs

G is gain of filter in dB
fc is center frequency of filter
fs is sampling frequency
Q is filter Q (quality) factor


Das könnte ja auch hinkommen, allerdings weiß ich nicht wie man dann aus 
den Float-Werten für die Koeffizienten das geforderte 4.20 Format macht.

Es setzt sich wohl so zusammen:
Vorzeichen, 2^3, 2^3,...2^0, 2^-1, 2^-2, ... 2^-19 und wird "irgendwie" 
dann auf 3 Byte verteilt.

Wäre froh, wenn mir da jemand weiterhelfen könnte.


M f G
Sebastian

von Florian (Gast)


Lesenswert?

Erst einmal musst Du Deine Werte auf den Bereich von 0 bis knapp unter 
16 normieren.

Deinen konkreten Wert kannst Du bekommen, indem Du die Float (am besten 
auf einem Prozessor oder µC, der mit 32-bit Werten umgehen kann), mit 
2^20 multiplizierst und in int bzw. das 32-bit Äquivalent umwandelst. 
Die unteren 24 Bits sind dann Dein gesuchter Wert.

Bsp:
1
float f = 3.14159;
2
3
long i = ( long ) ( f * pow( 2, 20 ) );
4
5
unsigned char s1 = ( unsigned char ) ( ( i >> 16 ) & 0xFF );
6
unsigned char s2 = ( unsigned char ) ( ( i >>  8 ) & 0xFF );
7
unsigned char s3 = ( unsigned char ) ( ( i       ) & 0xFF );

Durch diese Berechnung wird 2^3 zu 2^23 und 2^-20 zu 2^0 (also 1).

Wenn ich mich jetzt aufgrund der späten Stunde nicht um 1 Bit in 
irgendeine Richtung vertan habe, müsste das soweit passen.

von Florian (Gast)


Lesenswert?

OK, zur Sicherheit:
Nehmen wir aus dem Datenblatt mal irgendeinen Wert, z.B. -12 dB = 0x04, 
0x04, 0xDE.

Machen wir daraus eine Integer-Zahl:

0x0404DE = 263390

Teilen das mal durch 2^20 (=1048576), dann kommen wir auf 0.251188278

log(0.251188278) * 20 = -12.000012627

Passt also.

von Sebastian (Gast)


Lesenswert?

Hallo,

Vielen Dank für die Antwort, das hilft mir weiter.

Wäre ja auch nicht so aufwendig gewesen, die eine Zeile ("4.20" = 
floatwert *2^20) noch ins Datenblatt zu schreiben...

M f G
Sebastian

von Florian (Gast)


Lesenswert?

Aber ob das wirklich notwendig wäre? Man hat doch eigentlich ständig mit 
Festkommawerten zu tun.

von Sebastian (Gast)


Lesenswert?

Naja, ich mach sowas hier zum ersten Mal :)

Aber was anderes..
Ein Kumpel hat mir ein kleines Delphi Programm geschrieben, das mir die 
Koeffizienten anhand der o.g. Formeln berechnet und in Hex umrechnet. 
Das ganze Paket aus den 15 Byte kann ich nun über die serielle 
Schnittstelle schicken und schreibe es in den tas3002.
Das funktioniert soweit auch, allerdings klingen die Filter ganz und gar 
nicht wie sie sollten..

Vielleicht hast Du ja eine Idee was an den Formeln oben faul sein 
könnte.

von Florian (Gast)


Lesenswert?


von Sebastian (Gast)


Lesenswert?

Hallo,

Danke für den Link..
Es war noch ein kleiner Fehler in dem Berechnungsprogramm. Jetzt klappt 
alles. Habe es mal mit nem Spectrumanalyser überprüft.. alles supi :)

M f G
Sebastian

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.