Filter schneller berechnen, aber wie?

OP #587287
Lesenswert?

Hallo,
ich beschäftige mich gerade mit der Programmierung von IIR-Filtern. 
Meine ersten Filter habe ich auch sehr zuverlässig auf dem DSP Bord 
TMS320C6713 der Firma Texas Instruments programmiert. Da dieses Bord 
allerdings relativ teuer ist und ich die meisten Funktionen gar nicht 
benötige, habe ich mich nach einer günstigeren Lösung umgesehen. Dabei 
bin ich auf den ATmega32(µC) der Firma Atmel gestoßen, der wirklich 
günstig ist. Zudem ist der A/D-Wandler sogar noch schneller als beim 
Teaxas Instrument Bord. Mir war im Prinzip schon vorher klar, dass ich 
vermutlich Probleme bei der Lösung einer solchen Aufgabe mit einem µC 
bekomme. Schaut man sich allerdings den einfachen C-Code für ein IIR 
2.Ordnung an, kann man vielleicht nachvollziehen, warum ich es dennoch 
versucht habe.
1
// funktionen read_adc und send_dac stehen hier
2

3
void main (void)
4
 {
5
 float a0,a1,a2,b1,b2,u0=0,u1=0,u2=0,u3=0;  //Declare local variables
6
 a0 =  0.2083;     //Zählerkoeffizienten
7
 a1 =  0.4165;
8
 a2 =  0.2083;
9
 b1 =  0.0327;     //Nennerkoeffizienten
10
 b2 = -0.1996;
11

12
 while(1)
13
   {
14
   u0 = read_adc;   //Eingangswert vom AD,  
15
                    //Für Testzwecke Wert direkt zuweisen
16
   
17
   u3 = a0*u0+u2;
18
   u2 = a1*u0-b1*u3+u1;
19
   u1 = a2*u0-b2*u3;
20

21
   send_dac = u3;     //Für Testzwecke löschen
22
   };
23
 }

Zu Testzwecken habe ich den Funktionsaufruf send_dac herausgenommen und 
u0 einen float Wert direkt zugewiesen.
Nun benötigt der ATmega32 mit 14,745 MHz Quarztakt allerdings 160µs für 
einen Durchlauf der "While(1)-Endlosschleife", was für meine späteren 
Anwendungen viel zu langsam ist.
Nun endlich zu meiner Frage: Kennt jemand eine relativ günstige Lösung 
um z.B. die zeitraubenden Multiplikationen durch einen wesentlich 
schnelleren Hardwaremultiplizierer zu berechnen?
Oder einen Prozessor, FPGA o.ä., der einen solchen Durchlauf in ca.0,1µs 
(10MHz) schafft?
Da die maximale Ordnungszahl des Filters 10 betragen wird, würde mir 
auch eine Durchlaufzeit von ca. 3,2 MHZ - 1 MHz für die 10.Ordnung 
ausreichen.

Auch Anregungen und Ideen könnten mir weiterhelfen...

MfG
Chris
Gast #587304
Lesenswert?

Ich würde Deine 'Konstanten' a0-b2 auch als solche abspeichern:
1
const float a0 = 0.2083;

Dann hat der Compiler schon die Möglichkeit zu optimieren. Wenn sich die 
Werte natürlich dynamisch ändern sollen, geht das nicht.

Außerdem würde ich die Direktform I verwenden.

Es wäre auch denkbar, anstatt mit Gleitkommazahlen, mit Festkommazahlen 
zu arbeiten.
Dieser Beitrag ist gesperrt und kann nicht beantwortet werden.