UNIVERSITE Abdelmalek ESSADI
Ecole Nationale des Sciences Appliquées
- Tanger -
Compte rendu du TP3 « DSP »
Filtre IIR
Réalisée par :
- Rahmani Kehal Walid
- Ouzal Nour El Houda
- Majd Rasicm
- Yahya Saidi
Filière :
GSTR2
Objectifs
Cette partie va nous permettre de découvrir la synthétise d’un filtre à réponse
impulsionnelle infinie (IIR : Infinite Impulse Response) de type passe bas, d’implanter ce
filtre sur le DSP TMS320VC5416 et de vérifier son implantation.
Introduction
Le traitement du signal numérique (DSP) joue un rôle essentiel dans de nombreux
domaines tels que les télécommunications, l'audio, la vidéo, le contrôle industriel, etc. Les
filtres IIR (Infinite Impulse Response) sont largement utilisés en traitement du signal pour
leurs caractéristiques de réponses fréquentielles flexibles et leur efficacité de calcul.
L'objectif de ce travail pratique est d'implémenter un filtre IIR sur le DSP
TMS320VC5416, un processeur de signal numérique puissant et polyvalent. Le
TMS320VC5416 offre une combinaison de performances élevées, de faible consommation
d'énergie et de flexibilité, en faisant un choix idéal pour l'implémentation de filtres
numériques complexes.
Filtrage IIR
Un filtre IIR (Infinite Impulse Response) est un type de filtre numérique utilisé pour
traiter les signaux en appliquant une réponse fréquentielle spécifique. Il tire son nom du fait
que sa réponse impulsionnelle est infinie dans le temps. Contrairement aux filtres FIR
(Finite Impulse Response) dont la réponse impulsionnelle est de durée finie, les filtres IIR
utilisent une rétroaction (feedback) dans leur structure pour obtenir une réponse en
fréquence souhaitée.
La structure d'un filtre IIR est généralement basée sur une fonction de transfert
rationnelle, qui est le rapport de deux polynômes : le polynôme du numérateur et le
polynôme du dénominateur. Ces polynômes représentent respectivement les coefficients des
termes de rétroaction et d'alimentation directe du filtre.
Les filtres IIR sont couramment utilisés dans de nombreux domaines du traitement du
signal, tels que l'audio numérique, la communication sans fil, la détection de signal, la
suppression de bruit, etc. Leur efficacité de calcul et leurs caractéristiques de réponses
fréquentielles flexibles en font un choix populaire pour diverses applications de traitement
du signal.
L'une des caractéristiques importantes des filtres IIR est leur capacité à atteindre des
réponses fréquentielles plus complexes que les filtres FIR avec moins de coefficients. Les
filtres IIR peuvent être conçus pour avoir des caractéristiques de réponses fréquentielles
telles que des filtres passe-bas, passe-haut, passe-bande, ou coupe-bande, permettant de
filtrer sélectivement les composantes du signal dans différentes bandes de fréquence.
Implémentation du filtre sur DSP
A. Ouvrez le projet Project_IIR_Filter.pjt qui se trouve votre répertoire perso via
le menu Project/Open.
Il contient le fichier source C, les librairies, les fichiers de configuration de la mémoire de la carte DSP …
tout ce qui est nécessaire pour construire un programme exécutable.
B. Ouvrez le projet Project_IIR_Filter.pjt qui se trouve votre répertoire perso via
le menu Project/Open.
C. Analysez la structure générale de ce fichier ?
Ce code effectue le traitement d'un filtre passe-bas IIR sur un tableau de données d'entrée.
D. Fabriquez l’exécutable via la commande Project/Build. Le fichier exécutable
Project_IIR_Filter.out a été créé dans le répertoire debug du projet.
On exécute la commande Project/Build :
Le fichier Project_IIR_Filter.out a été créé :
Par la suite, nous utilisons une fréquence d’échantillonnage fe=80 KHz
largement supérieure à 2 fois la fréquence 8 KHz du signal haute fréquence
conformément au théorème de Shannon. Pour ce filtre, nous avons choisi
une fréquence de coupure de fc=1 KHz.
- Quel est le résultat obtenu pour une entrée caractérisée par les deux
fréquences 500 Hz et 8000 Hz dans le cas d’un filtre passe bas ?
Pour calculer la sortie du filtre passe-bas IIR pour les fréquences d'entrée de 500
Hz et 8000 Hz, nous devons utiliser les valeurs fournies dans le code pour les
coefficients du filtre.
Dans le code, les variables "a" et "b" représentent les coefficients du filtre. Les
calculs pour ces coefficients sont effectués à l'aide des valeurs de la fréquence de
coupure "fc" et de la fréquence d'échantillonnage "fs".
Selon les commentaires du code, les formules pour calculer les coefficients sont
les suivantes : d = 2 * to * fs;
a = 1 + d;
b = 1 - d;
La variable "to" représente la période de la fréquence de coupure, et "fs" est la
fréquence d'échantillonnage. Dans votre cas, "fc" est de 1 kHz et "fs" est de 80
kHz, comme indiqué.
Calculons les valeurs de "d", "a" et "b" :
to = 1 / (2 * π * fc)
= 1 / (2 * π * 1000)
= 1 / 6283.19
≈ 1.592 * 10^(-4)
d = 2 * to * fs
= 2 * 1.592 * 10^(-4) * 80000
≈ 25.472
a=1+d
= 1 + 25.472
≈ 26.472
b=1-d
= 1 - 25.472
≈ -24.472
Maintenant, nous pouvons appliquer ces coefficients au filtre passe-bas en
utilisant la formule de récurrence suivante :
sortie[i] = (1/a) * (-b * sortie[i-1] + entree[i] + entree[i-1])
Pour les fréquences d'entrée de 500 Hz et 8000 Hz, nous pouvons supposer que
les échantillons du signal d'entrée sont stockés dans le tableau "entree". Nous
itérerons à travers chaque échantillon et calculerons la valeur filtrée
correspondante pour chaque échantillon dans le tableau "sortie".
Voici le calcul pour les fréquences d'entrée de 500 Hz et 8000 Hz :
1. Fréquence d'entrée de 500 Hz :
- Supposons que l'échantillon du signal d'entrée soit "entree[i] = 1.0" pour un
certain "i".
- Appliquons la formule de récurrence :
sortie[i] = (1/26.472) * (-(-24.472) * sortie[i-1] + 1.0 + entree[i-1])
= 0.0378 * sortie[i-1] + 0.0378 * entree[i-1] + 0.0378
2. Fréquence d'entrée de 8000 Hz :
- Supposons que l'échantillon du signal d'entrée soit "entree[i] = 1.0" pour un
certain "i".
- Appliquons la formule de récurrence :
sortie[i] = (1/26.472) * (-(-24.472) * sortie[i-1] + 1.0 + entree[i-1])
- Changez le code du filtre passe bas par un code du filtre passe bande
?
#include <stdio.h>
#include "volume.h"
/* Global declarations */
float entree[BUFSIZE];
float sortie[BUFSIZE];
unsigned int processingLoad = BASELOAD; /* processing routine load value */
struct PARMS str = {2934, 9432, 213, 9432, &str};
/* Functions */
extern void load(unsigned int loadValue);
static void dataI(void);
int main()
{
int i;
float a, b, d, to, c, wb;
float fs = 80000, fc1 = 500, fc2 = 8000;
wb = 2 * 3.14 * 10;
to = 1 / (2 * 3.14 * ((fc1 + fc2) / 2));
d = 2 * to * fs;
a = 1 + d;
b = 1 - d;
c = 2 * wb * fs;
printf("d=%f\n", d);
for (i = 0; i < BUFSIZE; i++)
{
entree[i] = 0;
sortie[i] = 0;
}
printf("--Chargement des Données--\n");
dataI();
printf("**Filtre Passe-Bande**\n");
sortie[0] = (1 / a) * (b * entree[0]);
for (i = 1; i < BUFSIZE; i++)
{
sortie[i] = (1 / a) * (-b * sortie[i - 1] + b * entree[i] - b * entree[i - 1]);
printf("entree= %f\tsortie[%d]= %f\n", entree[i], i, sortie[i]);
}
return 0;
}
static void dataI()
{
/* do data I */
return;
Dans ce code modifié, nous avons adapté le filtre pour implémenter un filtre passe-bande en
utilisant les fréquences de coupure fc1 = 500 Hz et fc2 = 8000 Hz.
Les principaux changements apportés au code sont les suivants :
- Les variables fc1 et fc2 sont introduites pour représenter les fréquences de coupure
basse et haute du filtre passe-bande.
- La formule pour calculer le coefficient "to" est modifiée pour prendre en compte la
moyenne des fréquences de coupure : to = 1 / (2 * π * ((fc1 + fc2) / 2))
- La formule de récurrence pour le filtre passe-bande est modifiée pour refléter le filtre
passe-bande :sortie[i] = (1 / a) * (-b * sortie[i - 1] + b * entree[i] - b * entree[i - 1])
Les autres parties du code, telles que l'initialisation des tableaux et l'appel à la fonction
"dataI()", restent inchangées.
- Testez le filtre passe bande par un signal à l’entrée à fréquence variable ?
Ce code génère un signal sinusoïdal d'entrée pour chaque fréquence dans le tableau freqs[].
Le signal d'entrée est ensuite filtré par le filtre passe-bande et les valeurs de sortie
correspondantes sont affichées.
#include <stdio.h>
#include <math.h>
#include "volume.h"
/* Global declarations */
float entree[BUFSIZE];
float sortie[BUFSIZE];
unsigned int processingLoad = BASELOAD; /* processing routine load value */
struct PARMS str = {2934, 9432, 213, 9432, &str};
/* Functions */
extern void load(unsigned int loadValue);
static void dataI(void);
int main()
{
int i;
float a, b, d, to, c, wb;
float fs = 80000, fc1 = 500, fc2 = 8000;
float freqs[] = {100, 500, 1000, 3000, 8000}; // Fréquences d'entrée à tester
wb = 2 * 3.14 * 10;
to = 1 / (2 * 3.14 * ((fc1 + fc2) / 2));
d = 2 * to * fs;
a = 1 + d;
b = 1 - d;
c = 2 * wb * fs;
printf("d=%f\n", d);
for (i = 0; i < BUFSIZE; i++)
{entree[i] = 0;
sortie[i] = 0;
}
printf("--Chargement des Données--\n");
dataI();
for (int freqIndex = 0; freqIndex < sizeof(freqs) / sizeof(freqs[0]); freqIndex++)
{float freq = freqs[freqIndex];
printf("**Filtre Passe-Bande pour la fréquence d'entrée %f Hz**\n", freq);
for (i = 0; i < BUFSIZE; i++)
{
entree[i] = sin(2 * 3.14 * freq * i / fs); // Génération du signal sinusoïdal d'entrée
sortie[i] = 0;
}
sortie[0] = (1 / a) * (b * entree[0]);
for (i = 1; i < BUFSIZE; i++)
{
sortie[i] = (1 / a) * (-b * sortie[i - 1] + b * entree[i] - b * entree[i - 1]);
printf("entree= %f\tsortie[%d]= %f\n", entree[i], i, sortie[i]);
}
printf("\n");
}
return 0;
}
static void dataI()
{
/* do data I */
Conception et implémentation de filtre IIR sur MATLAB:
Déclaration des parametres :
N=4; : Ordre du filtre elliptique.
Rp=1; : Ondulation maximale en dB dans la bande passante.
Rs=40; : Atténuation minimale en dB dans la bande d'arrêt.
Wp=0.4; : Fréquence de coupure normalisée (par rapport à la fréquence de Nyquist).
Conception du filtre elliptique :
[b,a]=ellip(N,Rp,Rs,Wp); : Cette fonction conçoit un filtre passe-bas elliptique avec les
paramètres spécifiés. b et a sont les coefficients du numérateur et du dénominateur du filtre,
respectivement.
Affichage de la réponse fréquentielle :
freqz(b,a); : Cette fonction trace la réponse fréquentielle du filtre défini par les coefficients b
et a.
Calcul et vérification de la stabilité du filtre :
poles=roots(a); : Cette commande calcule les racines du polynôme caractéristique
(dénominateur) du filtre, ce qui correspond aux pôles du filtre.
if all(abs(poles)<1) : Cette condition vérifie si tous les pôles sont à l'intérieur du cercle unité
(c'est-à-dire, si les valeurs absolues des pôles sont toutes inférieures à 1), ce qui est une
condition nécessaire pour que le filtre soit stable.
disp('filtre est stable') : Affiche "filtre est stable" si tous les pôles sont à l'intérieur du cercle
unité.
else : Sinon,
disp('filtre n''est pas stable') : Affiche "filtre n'est pas stable" si un ou plusieurs pôles sont à
l'extérieur du cercle unité.
Lancement de fdatool sur MATLAB
Configuration d’un filtre IIR :
Comme on peut observer la réponse est infini car il s’agit d’un filtre impulsionnelle de réponse
infini.