Forum: Digitale Signalverarbeitung / DSP / Machine Learning IIR mit Festkommawerten in µC


von frieder (Gast)


Lesenswert?

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?

von frieder (Gast)


Lesenswert?

y und y sind natürlich vom vorzeichenbehafteten Typen int32_t.

von Detlef _. (detlef_a)


Lesenswert?

Mal 'l' ('l' wie lima) an die interger ranhängen. Für z.B. AVR sind 
integer 16 Bit lang und da passen Deine Zahlen nicht rein.
#define A2 65536l // 1

Vielleicht wars das schon, ansonsten den Algorithmus mal aufm PC laufen 
lassen.

Gute Nacht
Detlef

PS: 17Bit Coeff, 10Bit Daten , 5Bit für die Summanden, ein Bit fürs 
Vorzeichen, das gibt nen Overflow. Bißchen zurückhaltender rangehen, 
IIRs in integer zicken gerne

von frieder (Gast)


Lesenswert?

Das l-Suffix werde ich morgen mal testen.

Den Code hab ich sowohl auf einem PC getestet, als auch in Matlab - mit 
dem gleichen Ergebnis.

Die Koeffizienten hab ich auch mal ein paar Bits kleiner gemacht, nützt 
ebenso wenig.

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.