Outils pour utilisateurs

Outils du site


tns_nucleo_tp1

Différences

Ci-dessous, les différences entre deux révisions de la page.

Lien vers cette vue comparative

Les deux révisions précédentes Révision précédente
Prochaine révision
Révision précédente
tns_nucleo_tp1 [2019/03/28 17:27]
bvandepo
tns_nucleo_tp1 [2019/04/03 14:01] (Version actuelle)
bvandepo
Ligne 45: Ligne 45:
   - lancer eclipse via la console en tapant: ​  /​opt/​STM32/​SystemWorkbench/​eclipse  ​   - lancer eclipse via la console en tapant: ​  /​opt/​STM32/​SystemWorkbench/​eclipse  ​
   - Si une fenêtre "​Select a workspace"​ apparaît, saisir le nom de dossier: /​home/​IUT/<​login étudiant>/​workspace_ac6/​ et cocher "Use this as the default..."​   - Si une fenêtre "​Select a workspace"​ apparaît, saisir le nom de dossier: /​home/​IUT/<​login étudiant>/​workspace_ac6/​ et cocher "Use this as the default..."​
 +  - fermer l'​onglet "​Welcome"​ en cliquant sur la croix.
   - cliquer à gauche sur l'​icone C/C++   - cliquer à gauche sur l'​icone C/C++
   - cliquer droit dans project Explorer->​Import,​ puis General->​Existing Projects into Workspace   - cliquer droit dans project Explorer->​Import,​ puis General->​Existing Projects into Workspace
Ligne 59: Ligne 60:
  
  
-===Initialisation système de gestion de version=== +===Initialisation ​du système de gestion de version=== 
-Seulement après avoir importé le projet depuis l'​archive dans eclipse, saisir dans une nouvelle console:+Seulement après avoir importé le projet depuis l'​archive dans eclipse, saisir ​**dans une nouvelle console**:
   echo commence   echo commence
   cd ~/​workspace_ac6/​   cd ~/​workspace_ac6/​
Ligne 80: Ligne 81:
 Vous devrez affecter une bonne valeur à **htim1.Init.Period** pour obtenir la fréquence demandée. Il s'agit de la valeur correspondant au nombre de cycle -1 de décomptage du timer (chargée dans le registre nommé ARR lors du TD précédent),​ le prédiviseur étant réglé sur un facteur 1. Vous avez effectué un tel calcul lors du TD précédent. Vous devrez affecter une bonne valeur à **htim1.Init.Period** pour obtenir la fréquence demandée. Il s'agit de la valeur correspondant au nombre de cycle -1 de décomptage du timer (chargée dans le registre nommé ARR lors du TD précédent),​ le prédiviseur étant réglé sur un facteur 1. Vous avez effectué un tel calcul lors du TD précédent.
  
-Il faut ensuite compléter la fonction d'​interruption dans le fichier Src/main.c +Il faut ensuite compléter la fonction d'​interruption dans le fichier ​**Src/main.cpp**: 
 +<file cpp main.cpp>​
   void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim){   void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim){
-     //Code executé ​à la fréquence d'​interruption+     //Ecrire ici votre code exécuté ​à la fréquence d'​interruption
   }   }
-  ​+</​file>  ​
 ===Génération du signal sur la broche===  ​ ===Génération du signal sur la broche===  ​
  
Ligne 97: Ligne 98:
 {{https://​homepages.laas.fr/​bvandepo/​files/​iut/​tp_tns/​image_verso.jpg}} {{https://​homepages.laas.fr/​bvandepo/​files/​iut/​tp_tns/​image_verso.jpg}}
   ​   ​
-Les autres broches des connecteurs sont organisées tel que le montre le schéma suivant:+Les autres broches des connecteurs sont organisées tel que le montre le schéma suivant ​(la carte étant vue depuis le haut, composants face à vous):
 {{ ::​nucleo-f334_pinout.png?​800 |}} {{ ::​nucleo-f334_pinout.png?​800 |}}
  
Ligne 107: Ligne 108:
  
 === Compilation et téléchargement sur la cible en mode Debug === === Compilation et téléchargement sur la cible en mode Debug ===
 +Après l'​ouverture du projet, il est nécessaire de le compiler une première fois avant de pouvoir le debbuguer. Pour cela, cliquez sur le bouton: ​ {{ ::​build.png?​64 |}}
 +
 +
 +Brancher la carte Nucleo au port USB du PC.
  
 Pour activer le mode Debug : Pour activer le mode Debug :
Ligne 158: Ligne 163:
   ​   ​
  
 +<ifauth @prof> 
 +Solution: 
 +régler dans Src/tim.c 
 +   ​htim1.Init.Period = 1332; 
 +et 
 +<file cpp soluce.cpp>​ 
 + void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) 
 + { 
 + static uint32_t cpt = 0; 
 +//pour accès plus rapide aux broches 
 +       //​GPIOB->​ODR|=GPIO_PIN_11;​ 
 +       //​GPIOB->​ODR&​=~GPIO_PIN_11;​ 
 +//pour accès plus lent au broches, en passant par les registres de demande de mise à 1/0 
 + HAL_GPIO_WritePin(GPIOB,​ GPIO_PIN_11,​ GPIO_PIN_SET);​ 
 + if (cpt == 24000) 
 +
 + cpt = 0; 
 + HAL_GPIO_TogglePin(GPIOB,​ GPIO_PIN_13);​ 
 +
 + else 
 + cpt++; 
 + HAL_GPIO_WritePin(GPIOB,​ GPIO_PIN_11,​ GPIO_PIN_RESET);​ 
 + } 
 +</​file>​ 
 +</​ifauth>​ 
 + 
 ------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------
  
Ligne 169: Ligne 199:
 Les fonctions de la librairies math (sin, cos, tan ...) ne sont pas utilisables dans la fonction de gestion d'​interruption timer du fait de leur lenteur. Il faut donc définir un tableau contenant les échantillons précalculés d'une période de la fonction sinus pour la fréquence demandée. ​ Les fonctions de la librairies math (sin, cos, tan ...) ne sont pas utilisables dans la fonction de gestion d'​interruption timer du fait de leur lenteur. Il faut donc définir un tableau contenant les échantillons précalculés d'une période de la fonction sinus pour la fréquence demandée. ​
  
-Pour cela, compléter le code suivant ​(à coller où il faut ...). Les échantillons ainsi générés doivent couvrir la dynamique du convertisseur DAC (0 < = échantillon < = 4095). ​+Pour cela, copier dans le fichier main.cpp et compléter le code suivant:
  
  
Ligne 187: Ligne 217:
 </​file>​ </​file>​
  
-Pour déterminer la valeur des différents échantillons,​ vous pouvez vous inspirer du code écrit lors du TP4 de TNS qui est rappelé ​ici :+ 
 +Pour déterminer la valeur des différents échantillons,​ vous pouvez vous inspirer du code écrit lors du TP4 de TNS qui est rappelé ​ci-dessous. Les échantillons ainsi générés doivent être compris dans la dynamique du convertisseur DAC (0 < = échantillon < = 4095) et leur valeur moyenne doit être réglée au milieu cette plage. La constante $\pi$ est définie sous le nom **M_PI**. Dans la formule suivante, **Tech** est obtenue en inversant **SAMPLING_RATE**. 
  
 <file txt aide.txt>​ <file txt aide.txt>​
-  Ecrivez d'​abord l'​expression mathématique ​de chaque ​signal+  Ecrivez d'​abord l'​expression mathématique ​du signal:
    Ex : signal(t)=A.sin(2Π.fo.t) + Vmoy    Ex : signal(t)=A.sin(2Π.fo.t) + Vmoy
-  Déterminez alors la valeur du signal aux instants d'​échantillonnages.+  Déterminez alors la valeur du signal aux instants d'​échantillonnages:
    Ex : signal(k.Tech)=A.sin(2Π.fo.k.Tech) + Vmoy    Ex : signal(k.Tech)=A.sin(2Π.fo.k.Tech) + Vmoy
   Créez ensuite un tableau de taille nbEch (qui dépend de la durée voulue. Ex : tmax=duree=kmax.Tech d’où   Créez ensuite un tableau de taille nbEch (qui dépend de la durée voulue. Ex : tmax=duree=kmax.Tech d’où
Ligne 202: Ligne 234:
  
  
-Cette fonction est à appeler **une fois** au bon endroit dans le code de la fonction main, avant le lancement du timer, afin d'​éviter qu'une interruption timer ne survienne avant que le tableau soit initialisé:​ +La fonction ​**void init_sin_tabbed()** ​est à appeler **une seule fois** au bon endroit dans le code de la fonction ​**main()**, avant le lancement du timer, afin d'​éviter qu'une interruption timer ne survienne avant que le tableau soit initialisé:​ 
 +<file c call_sin_tabbed.c>​
   //Insérez ici l'​appel de votre fonction **init_sin_tabbed**   //Insérez ici l'​appel de votre fonction **init_sin_tabbed**
   HAL_TIM_Base_Start_IT(&​htim1);​ //Déjà mis en place   HAL_TIM_Base_Start_IT(&​htim1);​ //Déjà mis en place
   HAL_DAC_Start(&​hdac2,​ DAC2_CHANNEL_1);​ //Déjà mis en place   HAL_DAC_Start(&​hdac2,​ DAC2_CHANNEL_1);​ //Déjà mis en place
 +</​file>​
  
- +Ainsi, le tableau ​**sin_tabbed** contient les échantillons à utiliser dans la fonction d'​interruption.
-Ainsi, le tableau ​"sin_tabbed" ​contient les échantillons à utiliser dans la fonction d'​interruption.+
  
 ===Exploitation des échantillons dans la fonction d'​interruption Timer=== ===Exploitation des échantillons dans la fonction d'​interruption Timer===
Ligne 224: Ligne 256:
 La fonction à utiliser pour écrire sur la sortie du DAC est: **HAL_StatusTypeDef HAL_DAC_SetValue(DAC_HandleTypeDef* hdac, uint32_t Channel, uint32_t Alignment, uint32_t Data);**. Cette fonction écrit une valeur "​Data"​ sur canal "​Channel"​ du DAC "​hdac"​ avec l'​alignement "​Alignement"​. Utiliser comme valeur de premier argument **DAC_HandleTypeDef* hdac** configuré à **&​hdac2**. Pour le  canal du DAC utiliser **DAC2_CHANNEL_1** et pour l'​alignement **0**. La fonction à utiliser pour écrire sur la sortie du DAC est: **HAL_StatusTypeDef HAL_DAC_SetValue(DAC_HandleTypeDef* hdac, uint32_t Channel, uint32_t Alignment, uint32_t Data);**. Cette fonction écrit une valeur "​Data"​ sur canal "​Channel"​ du DAC "​hdac"​ avec l'​alignement "​Alignement"​. Utiliser comme valeur de premier argument **DAC_HandleTypeDef* hdac** configuré à **&​hdac2**. Pour le  canal du DAC utiliser **DAC2_CHANNEL_1** et pour l'​alignement **0**.
  
-Une fois le code complet, observez le signal généré à l'​oscilloscope sur la broche PA6 (indiquée par une étiquette sous la carte Nucléo). Mesurez la fréquence et l'​amplitude du signal sinusoïdal généré. Mesurez aussi le nouveau temps d'​exécution de la fonction d'​interruption sur la boche PB11 et reportez ces valeurs sur votre compte rendu. ​+Une fois le code complet, observez le signal généré à l'​oscilloscope sur la broche PA6 (indiquée par une étiquette sous la carte Nucléo). Mesurez ​la valeur moyenne, ​la fréquence et l'​amplitude ​crête à crête ​du signal sinusoïdal généré. Mesurez aussi le nouveau temps d'​exécution de la fonction d'​interruption sur la boche PB11 et reportez ces valeurs sur votre compte rendu.  
 +Mesurer la valeur moyenne, la fréquence et l'​amplitude crête à crête du signal en sortie du circuit de mise en forme sur la broche A1 de la carte LINE_OUT et en déduire le facteur d'​atténuation.
  
  
Ligne 238: Ligne 271:
   ​   ​
  
 +
 +<ifauth @prof>
 +Solution:
 +<file cpp soluce.cpp>​
 +
 +#include <​math.h>​
 +#define SAMPLING_RATE ​ ( 48000.0f)
 +#define SIN_FREQ ​ ( 480.0f)
 +#define SIN_AMP 2000.0f
 +#define SIN_TAB_SAMPLES_PER_PERIOD ((unsigned int) (SAMPLING_RATE / SIN_FREQ)) //Taille du tableau pour une période du signal sinus
 + ​uint32_t sin_tabbed[SIN_TAB_SAMPLES_PER_PERIOD];​
 + void init_sin_tabbed(){
 + unsigned int k ;
 + for(k = 0 ; k < SIN_TAB_SAMPLES_PER_PERIOD;​ k ++ ){
 + sin_tabbed[k] = SIN_AMP*sin( 2*M_PI *SIN_FREQ*k/​SAMPLING_RATE)+ 2048; //​Compléter ici par le calcul de la valeur des échantillons
 + //​signal(k.Tech)=A.sin(2Π.fo.k.Tech) + Vmoy
 + }
 + }
 +void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
 + {
 + static uint32_t k = 0;
 + HAL_StatusTypeDef ret= HAL_DAC_SetValue(&​hdac2,​DAC2_CHANNEL_1,​0,​sin_tabbed[k]);​
 + if (k>= SIN_TAB_SAMPLES_PER_PERIOD -1)
 + k=0;
 + else
 + k++;
 +//....
 + }
 +</​file>​
 +</​ifauth>​
  
 ------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------
Ligne 267: Ligne 330:
   HAL_StatusTypeDef HAL_ADC_Start(ADC_HandleTypeDef* hadc); // Lance la conversion ​   HAL_StatusTypeDef HAL_ADC_Start(ADC_HandleTypeDef* hadc); // Lance la conversion ​
   HAL_StatusTypeDef HAL_ADC_Stop(ADC_HandleTypeDef* hadc); // Stoppe la conversion ​   HAL_StatusTypeDef HAL_ADC_Stop(ADC_HandleTypeDef* hadc); // Stoppe la conversion ​
-  HAL_StatusTypeDef HAL_ADC_PollForConversion(ADC_HandleTypeDef* hadc, uint32_t Timeout); //Attend le résultat de la conversion, le deuxième paramètre permet de limiter le temps d'​attente. +  HAL_StatusTypeDef HAL_ADC_PollForConversion(ADC_HandleTypeDef* hadc, uint32_t Timeout); ​ 
-  uint32_t HAL_ADC_GetValue(ADC_HandleTypeDef* ​had) //Lit le résultat de la conversion+  ​//Attend le résultat de la conversion, le deuxième paramètre permet de limiter le temps d'​attente. 
 +  //Vous pouvez le régler à 10 
 +  uint32_t HAL_ADC_GetValue(ADC_HandleTypeDef* ​hadc) //Lit le résultat de la conversion
   ​   ​
 Les valeurs possibles du paramètre de retour **HAL_StatusTypeDef** sont :  **HAL_OK** , **HAL_ERROR** , **HAL_BUSY** et **HAL_TIMEOUT**. Les valeurs possibles du paramètre de retour **HAL_StatusTypeDef** sont :  **HAL_OK** , **HAL_ERROR** , **HAL_BUSY** et **HAL_TIMEOUT**.
Ligne 286: Ligne 351:
 {{:​img_20170327_130651.jpg?​0x500}} ​ {{:​img_20170327_130710.jpg?​0x500}} {{:​img_20170327_130651.jpg?​0x500}} ​ {{:​img_20170327_130710.jpg?​0x500}}
  
-  - Vérifiez la recopie correcte du signal d'​entrée sur la sortie.+  - Vérifiez la recopie correcte du signal d'​entrée sur la sortie ​(au facteur d'​amplification/​atténuation près).
   - Mesurez ensuite et reportez sur le compte rendu :   - Mesurez ensuite et reportez sur le compte rendu :
       - sur la broche PB12, mesurez le temps temps nécessaire à l'ADC pour effectuer une conversion.       - sur la broche PB12, mesurez le temps temps nécessaire à l'ADC pour effectuer une conversion.
Ligne 303: Ligne 368:
   echo fini   echo fini
   ​   ​
 +
 +<ifauth @prof>
 +Solution:
 +<file cpp soluce.cpp>​
 + HAL_GPIO_WritePin(GPIOB,​ GPIO_PIN_12,​ GPIO_PIN_SET);​
 + uint32_t ech;
 + HAL_ADC_Start(&​hadc1);​ // Lance la conversion
 + HAL_ADC_PollForConversion(&​hadc1,​ 10); //Attend le résultat de la conversion, le deuxième paramètre permet de limiter le temps d'​attente.
 + HAL_ADC_Stop(&​hadc1);​ // Stoppe la conversion
 + ech= HAL_ADC_GetValue(&​hadc1);​ //Lit le résultat de la conversion
 + HAL_GPIO_WritePin(GPIOB,​ GPIO_PIN_12,​ GPIO_PIN_RESET);​
 + HAL_StatusTypeDef ret= HAL_DAC_SetValue(&​hdac2,​DAC2_CHANNEL_1,​0,​ech);​
 +//​ HAL_StatusTypeDef ret= HAL_DAC_SetValue(&​hdac2,​DAC2_CHANNEL_1,​0,​sin_tabbed[k]);​
 +</​file>​
 +</​ifauth>​
 +
  
  
Ligne 321: Ligne 402:
   kill -9 3942   kill -9 3942
   ​   ​
 +  il faut aussi tuer tous les process dont le nom commence par  arm-none-
 </​ifauth>​ </​ifauth>​
  
 Pour tuer le processus du debugguer au cas où vous n'​auriez pas arreté le mode Debug avant de le relancer, copier coller dans une console: ​ Pour tuer le processus du debugguer au cas où vous n'​auriez pas arreté le mode Debug avant de le relancer, copier coller dans une console: ​
   kill -9 $(lsof -t  ~/​workspace_ac6/​nucleo_tns/​Debug/​nucleo_tns.elf)   kill -9 $(lsof -t  ~/​workspace_ac6/​nucleo_tns/​Debug/​nucleo_tns.elf)
 +  kill -9 $(lsof -t  -c arm-none-)
 +  ​
  
 +<ifauth @prof>
 +Pour gestion fine de la fréquence d'​interruption:​
  
 + cpt_it++;
 + if (cpt_it>​=3) {
 + htim1.Init.Period = 1333;
 + cpt_it=0;
 + }else{
 +   htim1.Init.Period = 1332;
 + }
 +
 +</​ifauth>​
tns_nucleo_tp1.1553790439.txt.gz · Dernière modification: 2019/03/28 17:27 par bvandepo