Ceci est une ancienne révision du document !
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_F ILTRE_0,memoireVk_filtre_0); HAL_TIM_Base_Start_IT(&htim1); //Déjà codé HAL_DAC_Start(&hdac2, DAC2_CHANNEL_1); //déjà codé
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 :
- 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).
- vérifiez les caractéristiques du signal avec l'oscilloscope
- brancher la sortie du générateur de signaux sur l'entrée A0 de la carte d'adaptation LINE_IN
- brancher l'entrée du scope sur la sortie A1 de la carte d'adaptation LINE_OUT
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. Mesurez le temps d'éxecution de la fonction de filtrage.