Hallo,
folgendes Problem:
Ich möchte auf einem 8-Bit-Mikrocontroller einen einfachen FIR-Filter 2.
Ordnung implementieren. Aus Performancegründen soll die Berechnung aber
nicht mit Fließ-, sondern mit Festkommazahlen laufen. Daher
multipliziere ich die von Matlab berechneten Koeffizienten a_i und b_i
mit hier 2^16. Bei Multiplikation mit den 10 Bit breiten Eingangswerten
x ist in einer 32 Bit Variablen also ausreichend Platz. Folgender Code
bringt mir bei meinem Tiefpass leider gar nix, das Eingangssignal wird
nicht geglättet:
1 | #define A0 65536 // ohne Multiplikation mit 2^16: 1
|
2 | #define A1 131072 // 2
|
3 | #define A2 65536 // 1
|
4 | #define B1 127376 // 1.943603515625
|
5 | #define B2 -62020 // -0.946350097656250
|
6 |
|
7 | uint16_t t, tmax;
|
8 | uint32_t x[1000], y[1000];
|
9 |
|
10 | for (t = 0; t < tmax; t++)
|
11 | {
|
12 | if (t >= 2)
|
13 | {
|
14 | y[t] = x[t] * A0 + x[t-1] * A1 + x[t-2] * A2 - B1*y[t-1] - B2*y[t-2];
|
15 | y[t] = y[t] >> 16)); // wieder zurücknormieren
|
16 | }
|
17 | else
|
18 | {
|
19 | y[t] = x[t];
|
20 | }
|
21 | }
|
Der Algorithmus konvergiert auch erst, wenn ich bei der Rücknormierung
einen größeren Wert als die 2^16 anwende.
Führe ich den Algorithmus jedoch ohne den zusätzlichen Faktor 2^16 und
mit double als Datentype aus, tritt die gewünschte Wirkung ein.
Jemand Ideen?