Outils pour utilisateurs

Outils du site


td2_tns

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
td2_tns [2015/03/09 23:48]
jpiat [Configuration et utilisation de l'ADC]
td2_tns [2016/03/29 17:00] (Version actuelle)
bvandepo [Configuration du timer 2 en générateur d'interruptions]
Ligne 1: Ligne 1:
 +
 ====== TD 2 Architecture pour le TNS : Périphériques et gestion du temps ====== ====== TD 2 Architecture pour le TNS : Périphériques et gestion du temps ======
 L'​objectif de ce TD et de savoir configurer les périphériques d'une plate-forme micro-contrôleur pour la gestion du temps et l'​interaction avec des signaux analogiques. L'​objectif de ce TD et de savoir configurer les périphériques d'une plate-forme micro-contrôleur pour la gestion du temps et l'​interaction avec des signaux analogiques.
Ligne 9: Ligne 10:
 [[http://​homepages.laas.fr/​bvandepo/​files/​iut/​Atmega328p_timer2.pdf]] [[http://​homepages.laas.fr/​bvandepo/​files/​iut/​Atmega328p_timer2.pdf]]
  
-L'Atmega329 ​dispose de 4 timers :+L'Atmega328 ​dispose de 4 timers :
  - Timer 0 : 8-bit avec PWM  - Timer 0 : 8-bit avec PWM
  - Timer 1 : 16-bit avec PWM  - Timer 1 : 16-bit avec PWM
Ligne 23: Ligne 24:
   - Proposer une configuration du timer 2 pour générer des événements à la fréquence de 16kHz et implémenter la fonction **setupTimerCTC(unsigned char clk_prescaler,​ unsigned char period)**   - Proposer une configuration du timer 2 pour générer des événements à la fréquence de 16kHz et implémenter la fonction **setupTimerCTC(unsigned char clk_prescaler,​ unsigned char period)**
  
 +<ifauth @prof>
 +===Solution:​===
 +  mode clear timer & compare (CTC)
 +  PRESCALER et OCR2A
 +  division par 1000
 +</​ifauth>​
  
 =====Configuration du timer 2 en générateur d'​interruptions ===== =====Configuration du timer 2 en générateur d'​interruptions =====
Ligne 41: Ligne 48:
   - reprendre le code de configuration précédent et ajouter la génération d'​interruption pour la comparaison avec OCR2A.   - reprendre le code de configuration précédent et ajouter la génération d'​interruption pour la comparaison avec OCR2A.
  
 +
 +
 +<ifauth @prof>
 +===Solution:​===
 +<file cpp configtimer.cpp>​
 +void setupTimer2(unsigned char prescaler, unsigned int period){
 +  TCCR2A = 0;// set entire TCCR2A register to 0
 +  TCCR2B = 0;// same for TCCR2B
 +  TCNT2  = 0;//​initialize counter value to 0
 +  OCR2A = period;
 +  // turn on CTC mode
 +  TCCR2A |= (1 << WGM21);
 +  TCCR2B |= prescaler & 0x7; // config of prescaler
 +  // enable timer compare interrupt
 +  TIMSK2 |= (1 << OCIE2A); ​
 +}
 +</​file>​
 +</​ifauth>​
  
 =====Configuration et utilisation de l'ADC ===== =====Configuration et utilisation de l'ADC =====
Ligne 46: Ligne 71:
 [[http://​homepages.laas.fr/​bvandepo/​files/​iut/​Atmega328p_can.pdf]] [[http://​homepages.laas.fr/​bvandepo/​files/​iut/​Atmega328p_can.pdf]]
  
-L'​Atmega328 dispose ​de d'un convertisseur analogique numérique à 6 canaux. Ce convertisseur est capable de convertir les données au rythme de 15ksps avec 10 bits de résolution.+L'​Atmega328 dispose d'un convertisseur analogique numérique à 6 canaux. Ce convertisseur est capable de convertir les données au rythme de 15ksps avec 10 bits de résolution.
  
 Questions :  Questions : 
Ligne 53: Ligne 78:
   - Écrire le code permettant de démarrer une conversion et lire le résultat **unsigned int readADCPolling()**   - Écrire le code permettant de démarrer une conversion et lire le résultat **unsigned int readADCPolling()**
  
 +<ifauth @prof>
 +===Solution:​===
 +<file cpp adc1.cpp>​
 +  void setupADCPolling()
 +  {
 +        ADCSRB=0; ​
 + ADCSRA ​  = 1 << ADPS2 | 1 << ADPS1 | 1 << ADPS0 | 1 << ADEN; // div 128, enabled
 +        ADMUX    = 1 << 6;  //choix entrée analogique 0 et référence de tension =VCC
 +  }
 +  /*! \brief ADC Conversion Routine in single ended mode */
 +  unsigned int readADCPolling(void)
 +  {
 +  unsigned int result;
 + ADCSRA ​ |= (1<<​ADSC);​ //​ Start ADC Conversion
 + while((ADCSRA & (1<<​ADIF)) != 0x10); // Wait till conversion is complete
 + result ​  = ADC;                         // Read the ADC Result
 + ADCSRA ​ |= (1 << ADIF); // Clear ADC Conversion Interrupt Flag
 +       ​return result ;
 +  }
 +  </​file>​
 +</​ifauth>​
 +
 +
 +
 +<ifauth @prof>
 +TODO: expliquer la décomposition en 2 fonctions
 +
 +<file cpp adc2.cpp>​
 +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////​
 +/*! \brief ADC Conversion Routine start */
 +inline void startReadADCPolling(void)
 +{
 +  ADCSRA ​ |= (1 << ADSC);​  ​       // Start ADC Conversion
 +}
 +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////​
 +/*! \brief ADC Conversion Routine wait and read */
 +inline unsigned int finishReadADCPolling(void)
 +{
 +  unsigned int result;
 +  while ((ADCSRA & (1 << ADIF)) != 0x10); // Wait till conversion is complete
 +  result ​  = ADC;                                              // Read the ADC Result
 +  ADCSRA ​ |= (1 << ADIF);​  ​       // Clear ADC Conversion Interrupt Flag
 +  return result ;
 +}
 +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////​
 +</​file>​
 +</​ifauth>​
  
 Le convertisseur de l'​Atmega328 est capable de fonctionner en mode "free running"​. Dans ce mode l'ADC effectue la conversion du canal sélectionné aussi rapidement que possible est génère une interruption de fin de conversion. La routine d'​interruptions associée peut alors lire le résultat de la conversion sans attente. Le convertisseur de l'​Atmega328 est capable de fonctionner en mode "free running"​. Dans ce mode l'ADC effectue la conversion du canal sélectionné aussi rapidement que possible est génère une interruption de fin de conversion. La routine d'​interruptions associée peut alors lire le résultat de la conversion sans attente.
Ligne 59: Ligne 131:
   - Avec la configuration établie précédemment,​ à quel rythme l'ADC déclenchera t-il des conversions s'il est utilisé en mode free-running.   - Avec la configuration établie précédemment,​ à quel rythme l'ADC déclenchera t-il des conversions s'il est utilisé en mode free-running.
  
 +<ifauth @prof>
 +===Solution:​===
 +Interruption matérielle générée tous les 13 cycles de l'​horloge ADC.
 +</​ifauth>​
 +
 +Le convertisseur de l'​Atmega est également capable de générer des conversions au rythme défini par le Timer1/0, le comparateur analogique ou une interruption externe. (voir  p251, ADC auto trigger source selection).
  
-Le convertisseur de l'​Atmega est également capable de générer des conversions au rythme défini par le Timer1/0, le comparateur analogique ou une interruption externe. ​ 
 =====Configuration et utilisation du DAC ===== =====Configuration et utilisation du DAC =====
  
Ligne 106: Ligne 183:
 ===== Mise en place de l'​achitecture logicielle pour le TNS ===== ===== Mise en place de l'​achitecture logicielle pour le TNS =====
  
-A l'​aides des briques logicielles définies précédemment,​ mettre en place le squelette du programme Arduino avec :+A l'​aides des briques logicielles définies précédemment,​ mettre en place le squelette du programme Arduino avec la fonction **void setup(void)** réalisant: 
 +   - la configuration de l'ADC pour effectuer des conversions sur le canal 0 en mode déclenché par logiciel (setupADCPolling()) 
 +  - la configuration du DAC TLV5637 pour générer des tensions entre 0 et 4.096v 
 +  - la configuration du timer 2 pour générer une interruption à la fréquence de 2kHz 
 +  - la configuration de l'UART matériel à 9600 bauds 
 +  - la configuration de la GPIO 8 (port B bit 0)  en sortie 
 +  - l'​initialisation du filtre 
 + 
 +La fonction **void loop(void)** devra juste:  
 +  - envoyer la chaine "Je suis vivant"​ sur l'UART matériel.
  
-  - Le timer 2 configuré pour générer une interruption à la fréquence de 2kHz +La fonction d'interruption ​Timer appelée ​à la fréquence de 2kHz devra: 
-    - la GPIO 13 sera mise à un au début du gestionnaire d'​interruption  +  mettre à 1 la GPIO 8 (port B bit 0) au début du gestionnaire d'​interruption. 
-    - la fonction ​readAdcPolling() est appelée et le résultat de la conversion stocké dans la variable sample_t +  appeler ​la fonction ​**startReadADCPolling()**. 
-    - la fonction d'​écriture sur le DAC est appelée ​avec la variable ​sample_t mise à l'échelle +  appeler ​la fonction d'​écriture sur le DAC  avec la variable ​skprec pour la voie A et eksuiv pour la voie B. 
-    - la GPIO 13 sera mise à zéro à la fin du gestionnaire d'​interruption  +  - appliquer ​l'équation de récurrence du filtre en injectant l'​échantillon eksuiv et en récupérant la valeur de l'​échantillon de sortie skprec 
-  - L'ADC configuré pour effectuer des conversions sur le canal 0 en mode déclenché par logiciel (setupADCPolling()) +  appeler ​la fonction **finishReadADCPolling()** et stocker le résultat de la conversion dans la variable eksuiv. 
-  - Le DAC TLV5637 configuré pour générer des tensions entre 0 et 4.96v+  - mettre ​à 0 la GPIO 8 (port B bit 0)  ​à la fin du gestionnaire d'​interruption  
 + 
td2_tns.1425941317.txt.gz · Dernière modification: 2015/03/09 23:48 par jpiat