J'essaie d'implémenter un simple filtre IIR de premier ordre sur un MCU (PIC24FJ32GA002), sans succès jusqu'à présent. Le filtre est un filtre de suivi CC (filtre passe-bas) dont le but est de suivre la composante CC d'un signal de 1,5 Hz. L'équation de différence est tirée d'une note d'application TI:
y (n) = K x (n) + y (n-1) (1-K)
avec K = 1/2 ^ 8
J'ai fait un script MATLAB pour le tester et ça marche bien dans la simulation.Code utilisé:
K = 1/2 ^ 8b = Ka = [1 - (1-K)] Fs = 200; // fréquence d'échantillonnage Ts = 1 / Fs; Nx = 5000; // nombre d'échantillons nT = Ts * (0: Nx-1); fin = 1,5; // fréquence du signalrandn ('état', somme (100 * horloge)); noise = randn (1, Nx); noise = noise-mean (noise); xin = 200 + 9 * (cos (2 * pi * fin * nT)); xin = xin + noise; out = filter (b, a, xin);
Cependant, je ne peux pas implémentez-le sur un microcontrôleur PIC24F. Je représente les coefficients au format Q15 (1.15), en les stockant dans des variables courtes et en utilisant une longue pour les multiplications. Voici le code:
short xn; short y; short b0 = 128, a1 = 32640; // Q15long aux1, aux2; // (...) while (1) {xn = readADC (adc_ch); aux1 = ((long) b0 * xn) << 1; aux2 = ((long) a1 * y) << 1; y = ((aux1 + aux2) >> 16); delay_ms (5);}
Un cast long est utilisé pour étendre le signal afin que l'opération de multiplication soit effectuée correctement. Après chaque multiplication, je décale un bit vers la gauche pour supprimer le bit de signal étendu. Lors de la sommation, je décale 16 bits vers la droite pour obtenir y au format Q15.
Je débogue le MCU avec Pickit2 et la fenêtre «View-> Watch» (MPLAB IDE 8.53) et teste le filtre avec un signal CC (I changer le signal DC avec un potentiomètre pour tester différentes valeurs). L'ADC a une résolution de 10 bits et le MCU est fourni avec 3,3 V. Quelques résultats:
1V -> xn = 312 (correct), yn = 226 (incorrect)
1,5V -> xn = 470 (correct), yn = 228 (complètement faux)
Qu'est-ce que je fais de mal? Des suggestions sur la façon d'implémenter ce filtre IIR sur un MCU 16 bits?
Merci d'avance :)