Cours architecture pour le TNS cours_Archi_TNS_intro5_6ppf.pdf
La démarche de développement est composée de deux grandes étapes. La première étape consiste en l'implémentation d'un filtre logiciel qui permet de vérifier si le filtre possède bien les propriétés temporelles et/ou fréquentielles souhaitées. Cette étape réalisée lors des séances de TNS est composée de la façon suivante:
La seconde étape consiste en la réalisation concrète du filtre en tenant compte du matériel utilisé, le programme devant assurer les tâches suivantes:
Pour récupérez le fichier zip du projet la première fois, ouvrir une console (alt+F2 et taper lxterm) puis taper dedans:
cd /mnt/etu/s4en/..... à compléter pour aller dans votre dossier étudiant, en pressant 2 fois la touche TAB
puis ENSUITE SEULEMENT copier coller (sélectionner le code qui suit puis clic sur le bouton central de la souris dans le terminal) :
wget https://bvdp.inetdoc.net/files/iut/tp_tns/TP_ARCHI_TNS_2017.zip unzip TP_ARCHI_TNS_2017.zip cd TP_ARCHI_TNS qtcreator TP_ARCHI_TNS.pro & echo "C est bon !"
à l'ouverture de qtcreator, cliquer sur “Configurer le projet”
Jusqu'à ce TP, vous avez utilisé la fonction void calculReponseFiltre(sFiltre * pFiltre, double * ek, double * sk, int nbPts) pour appliquer le calcul de la réponse d'un filtre. Pour réaliser un filtre capable de traiter des échantillons en ligne, il faut que le processeur effectue le calcul de l'équation de récurrence échantillon par échantillon. La première partie du TP consiste donc à implémenter une fonction double filtreUnEchantillon(double ek) qui réalise le calcul de cette équation de récurrence.
Afin de pouvoir tester cette fonction, la fonction void calculReponseFiltreEnLigne(sFiltre * pFiltre, double * ek, double * sk, int nbPts):
void calculReponseFiltreEnLigne(sFiltre * pFiltre, double * ek, double * sk, int nbPts) { initFiltreUnEchantillon(pFiltre); for (int k=0; k < nbPts; k++) { sk[k] = filtreUnEchantillon(ek[k]); } }
Lire le code de la fonction initFiltreUnEchantillon et indiquer son rôle sur le compte rendu. Implémenter la fonction filtreUnEchantillon pour qu'elle retourne la valeur de l'échantillon e_k multiplié par 3. Compiler et exécuter le programme. Interpréter les réponses affichées. Quelle est l'équation correspondant à ce filtre ?
On cherche maintenant à implémenter l'équation: .
Afin de faciliter la transition vers les filtres RII, on supposera que les sont équivalents aux et l'équation à coder sera donc: .
Pour calculer , il est nécessaire de disposer des valeurs des coefficients du filtres et des échantillons d'entrée courant et précédents, stockés dans un buffer circulaire tel que présenté dans le cours.
La figure suivante illustre le fonctionnement d'un tel buffer de taille 6:
Le tableau memoireVk est utilisé pour stocker les échantillons. La variable globale indice_ecr est utilisée pour indiquer le numéro (indice d'écriture) de la case dans laquelle ranger l'échantillon le plus récent.
Compléter la fonction double filtreUnEchantillon(double ek) pour qu'elle:
Dans le codage, vous tiendrez compte du fait que le tableau memoireVk est circulaire et de taille MEMORYSIZE éléments pour la mise à jour des indices de lecture et d'écriture.
Tester votre fonction à l'aide du filtre dont les coefficients sont définis dans le tableau coeffB du fichier tparchi1.cpp.
Vérifier l'exactitude des réponses impulsionnelles et indicielles pour le filtre fourni jusque .
Appliquer ce filtre à deux sinusoïdes de fréquence 50 Hz et 500 Hz. Expliquez le résultat en vous aidant du module de la fonction de transfert.
On cherche maintenant à implémenter l'équation: .
Pour cela, nous utiliserons la forme vue en cours: faisant intervenir les termes . Pour l'échantillon , il est nécessaire d'évaluer la valeur de qui utilise les valeurs des précédemment calculés.
Compléter la fonction double filtreUnEchantillon(double ek) pour qu'elle permette de gérer ce type de filtre. Pour cela, vous y ajouterez avant le calcul de :
Tester l'implémentation de la fonction de calcul sur le filtre.
Déclarer les variables nécessaires pour ajouter un second filtre d'équation de récurrence:
Calculer les réponses impulsionnelles et indicielles en utilisant la fonction calculReponseFiltreEnLigne et ajouter le code permettant de les afficher. Superposer l'affichage du module de la fonction de transfert de ce filtre à l'affichage précédent.
Dans la démarche qui consiste à se rapprocher des conditions réelles dans lesquelles la fonction FiltreUnEchantillon sera utilisée, nous souhaitons maintenant intégrer les convertisseurs dans la chaîne de traitement en les simulant par des fonctions:
Le schéma suivant représente l'agencement de ces deux fonctions relativement à FiltreUnEchantillon.
Les fonctions simuADC et simuDAC sont définies dans les fichiers convertisseurs.cpp et .h que vous devez créer dans votre projet (Nouveau Fichier → C++ → source ou entête) et dans lesquels vous copier/collerez le contenu suivant:
double SimuADC ( double Ve, double Vmin, double Vmax, int nbBits); double SimuDAC ( double M, double Vmin, double Vmax, int nbBits);
#include <math.h> /*! * \brief SimuADC simule un ADC avec sortie non signée */ double SimuADC ( double Ve, double Vmin, double Vmax, int nbBits) { double q = (Vmax-Vmin)/(pow(2,nbBits)-1); double ekQuant; if (Ve<Vmin) ekQuant = 0; else if (Ve>Vmax) ekQuant = pow(2,nbBits)-1; else ekQuant = round((Ve-Vmin)/q); return ekQuant; } /*! * \brief SimuDAC simule un DAC avec entrée non signée */ double SimuDAC ( double M, double Vmin, double Vmax, int nbBits) { double q = (Vmax-Vmin)/(pow(2,nbBits)-1); return (Vmin + q*( (unsigned int)M % (1<<nbBits)) ); }
Comme cela a été dit en introduction de ce TP (relisez là si vous avez oublié…) il faut maintenant inclure les convertisseurs analogique↔numérique dans calculReponseFiltreEnLigne(). Déclarez vmin, vmax, nbbits comme constantes globales.