Outils pour utilisateurs

Outils du site


tns_nucleo_filtre

Mise en place de la fonction de filtrage

Une fois le DAC et l'ADC mis en place, nous pouvons à présent utiliser la fonction de filtrage filtreUnEchantillon déjà codée sour Qt. Pour cela, il vous d'abord ajouter au projet les fichiers : filtre.h, filtre.c donnés dans la suite. Pour cela, il vous faut cliquer sur le répertoire Src puis New → Source File.

et entrer le nom du fichier filtre.c

et faire la meme chose pour le fichier d'entete en cliquant sur le répertoire Inc puis New → Header File :

et entrer le nom de fichier filtre.h.

Vous pouvez ensuite copier le contenu des fichiers correspondant (donnés dans la suite).

filtre.h
/*
 * filtre.h
 *
 *  Created on: Mar 24, 2017
 *      Author: jpiat
 */
 
#ifndef FILTRE_H_
#define FILTRE_H_
 
#ifndef FILTRE_H
#define FILTRE_H
 
typedef struct sFiltre
{
    int nbCoeffB;
    float * pCoeffB;
    int nbCoeffA;
    float * pCoeffA;
    int nbMemoireVk;
    float * memoireVk;
    int memoireIndiceEcr;
}sFiltre;
 
 
void initFiltre( sFiltre * pFiltre, int nbInitB, float *pBInit, int nbInitA, float *pAInit,int nbMemoireVkInit, float *memoireVkInit);
float filtreUnEchantillon(float ek);
void initFiltreUnEchantillon(sFiltre * pFiltre);
 
#endif // FILTRE_H
 
#endif /* FILTRE_H_ */
file.c
#include "filtre.h"
#include <math.h>
 
/////////////////////////////////////////////////////////////////
const int OFFSET_ENTREE=2048;
const int OFFSET_SORTIE=2048;
const int VALEUR_MAX=2047;
const int VALEUR_MIN=-2048;
 
 
int NB_COEFF_B;
int NB_COEFF_A;
int MEMORYSIZE;
float *b;           //Coefficients du numérateur de la fonction de transfert du filtre
float *a;           //Coefficients du dénominateur de la fonction de transfert du filtre
                     //le premier élement est a1
                     //le tableau denCoeffs est de taille 1 pour un RIF
float *memoireVk;  //buffer rotatif pour stocker les valeurs de vk
int indice_ecr;              //indice d'écriture dans le buffer rotatif memoireVk
/////////////////////////////////////////////////////////////////
 
 
void initFiltre(sFiltre * pFiltre, int nbInitB, float *pBInit, int nbInitA, float *pAInit,int nbMemoireVkInit, float *memoireVkInit)
{
    pFiltre->nbCoeffB = nbInitB;
    pFiltre->pCoeffB = pBInit;
    pFiltre->nbCoeffA = nbInitA;
    pFiltre->pCoeffA = pAInit;
    pFiltre->nbMemoireVk = nbMemoireVkInit;
    pFiltre->memoireVk = memoireVkInit;
    pFiltre->memoireIndiceEcr = 0 ;
    initFiltreUnEchantillon(pFiltre); // devrait etre appelé juste avant filtreUnEchantillon
}
 
void initFiltreUnEchantillon(sFiltre * pFiltre){
    int i;
    //met à jour les variables globales
    NB_COEFF_B=  pFiltre->nbCoeffB;
    b= pFiltre->pCoeffB;
    NB_COEFF_A= pFiltre->nbCoeffA;
    a= pFiltre->pCoeffA;
    MEMORYSIZE=pFiltre->nbMemoireVk;
    memoireVk=pFiltre->memoireVk;
    indice_ecr=pFiltre->memoireIndiceEcr ;
}
/////////////////////////////////////////////////////////////////
float filtreUnEchantillon(float ek){
  //  FAIRE LE CODAGE DE CETTE FONCTION
}

Il vous faut ensuite récupérer le contenu de votre fonction filtreUnEchantillon codé sou Qt et le copier dans le fichier filtre.c (à l'endroit prévu). Etant donné que notre micro-controlleur ne sait pas gérer nativement le type double il vous faut remplacer toute référence à double par float.

Initialisation et utilisation du filtre

avant le code de gestion d'intterruption, copiez le contenu suivant (/* USER CODE BEGIN 0 */ doit vous servir de repère):

/* USER CODE BEGIN 0 */
#include "filtre.h"
#define NB_COEFF_B_FILTRE_0 6
float coeffB_filtre_0[NB_COEFF_B_FILTRE_0]={1,0,0,0,0,0};
#define NB_COEFF_A_FILTRE_0 1
float coeffA_filtre_0[NB_COEFF_A_FILTRE_0]={1};
#define MEMORYSIZE_FILTRE_0 6
float memoireVk_filtre_0[MEMORYSIZE_FILTRE_0];
sFiltre filtre_0;

puis dans la fonction main, avant le démarrage du timer (/* USER CODE BEGIN 2 */ doit vous servir de repère):

/* USER CODE BEGIN 2 */
initFiltre(&filtre_0,NB_COEFF_B_FILTRE_0,coeffB_filtre_0,NB_COEFF_A_FILTRE_0,coeffA_filtre_0,MEMORYSIZE_FILTRE_0,memoireVk_filtre_0);
HAL_TIM_Base_Start_IT(&htim1); //Déjà codé
HAL_DAC_Start(&hdac2, DAC2_CHANNEL_1); //déjà codé

egin, il vous faut appeler la fonction filtreUnEchantillon dans la fonction d'interruption sur l'échantillon capturé.

Le code de la fonction d'interruption doit maintenant éxecuter :

  • Activer la sortie connectée à la LED (déjà mis en place dans l'exercice précédent)
  • Lancer une conversion sur l'ADC
  • Attendre la fin de la conversion (HAL_ADC_PollForConversion doit retourner HAL_OK)
  • Récupérer le résultat de la conversion
  • Stopper le convertisseur
  • Apliquer la fonction de filtrage filtreUnEchantillon sur l'échantillon capturé
  • Désactiver la sortie connectée à la LED (déjà mis en place dans l'exercice précédent)
  • Ecrire l'échantillon filtré sur le DAC

Une fois le code du filtre mis en place il vous faut le tester. Pour ce test, la carte Nucléo est associée à deux cartes : LINE_IN, LINE_OUT pour adapter les niveaux et protéger l'entrée ADC du micro-controleur. L'adaptation en entrée applique un gain de 4.54 sur le signal mis en entrée et le centre sur 1.65v.

La procédure de test est la suivante :

  1. configurer le canal génération de signal de l'oscilloscope pour une sinusoide à 400Hz centrée sur 0 avec une amplitude réglée pour ne pas saturer l'amplificateur de la carte LINE_IN (vcc=3.3v).
  2. vérifiez les caractéristiques du signal avec l'oscilloscope
  3. brancher la sortie du générateur de signaux sur l'entrée A0 de la carte d'adaptation LINE_IN
  4. brancher l'entrée du scope sur la sortie A1 de la carte d'adaptation LINE_OUT

img_20170327_130651.jpg img_20170327_130710.jpg

Le filtre de base est un filtre de recopie. A partir des caractéristiques du signal d'entrée, vérifiez la validité du signal de sortie. Il vous maintenant mesurer :

  • le temps d'éxecution total de la fonction d'interruption
  • le temps d'éxecution de la fonction de filtrage

en déplaçant l'appel des fonctions de mise à un et mise à zéro de la LED (mesure sur la broche PA5). En déduire le temps de calcul associé à un coefficient pour le filtre FIR.

tns_nucleo_filtre.txt · Dernière modification: 2017/03/28 11:11 par jpiat