Ich versuche bisher ohne Erfolg, ein einfaches IIR-Filter erster Ordnung auf einer MCU (PIC24FJ32GA002) zu implementieren. Das Filter ist ein DC-Tracking-Filter (Tiefpassfilter), dessen Zweck darin besteht, die DC-Komponente eines 1,5-Hz-Signals zu verfolgen. Die Differenzgleichung wurde einer TI-Anwendungsnotiz entnommen:
y (n) = K x (n) + y (n-1) (1-K)
mit K = 1/2 ^ 8
Ich habe ein MATLAB-Skript erstellt, um es zu testen, und es funktioniert gut in der Simulation. Verwendeter Code:
K = 1/2 ^ 8b = Ka = [1 - (1-K)] Fs = 200; // AbtastfrequenzTs = 1 / Fs; Nx = 5000; // Anzahl der Proben nT = Ts * (0: Nx-1); fin = 1,5; // Signalfrequenzrandn ('Zustand', Summe (100 * Takt)); Rauschen = Randn (1, Nx); Rauschen = Rauschmittelwert (Rauschen); xin = 200 + 9 * (cos (2 * pi * fin *) nT)); xin = xin + Rauschen; out = Filter (b, a, xin);
Ich kann es jedoch nicht Implementieren Sie es auf einem PIC24F-Mikrocontroller. Ich stelle die Koeffizienten im Q15 (1.15) -Format dar, speichere sie in kurzen Variablen und verwende einen langen für Multiplikationen. Hier ist es der Code:
kurz xn; kurz y; kurz b0 = 128, a1 = 32640; // Q15long aux1, aux2; // (...) while (1) {xn = readADC (adc_ch); aux1 = ((lang) b0 * xn) << 1; aux2 = ((lang) a1 * y) << 1; y = ((aux1 + aux2) >> 16); delay_ms (5);}
Long Cast wird verwendet, um das Signal so zu erweitern, dass die Multiplikationsoperation korrekt ausgeführt wird. Nach jeder Multiplikation verschiebe ich ein Bit nach links, um das erweiterte Signalbit zu entfernen. Beim Summieren verschiebe ich 16 Bit nach rechts, um y im Q15-Format zu erhalten.
Ich debugge die MCU mit Pickit2 und dem Fenster "View-> Watch" (MPLAB IDE 8.53) und teste den Filter mit einem DC-Signal (I. Ändern Sie das Gleichstromsignal mit einem Potentiometer, um verschiedene Werte zu testen. Der ADC hat eine Auflösung von 10 Bit und die MCU wird mit 3,3 V geliefert. Einige Ergebnisse:
1 V -> xn = 312 (richtig), yn = 226 (falsch)
1,5 V -> xn = 470 (richtig), yn = 228 (völlig falsch)
Was mache ich falsch? Irgendwelche Vorschläge zur Implementierung dieses IIR-Filters auf einer 16-Bit-MCU?
Vielen Dank im Voraus :)