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/16 13:09]
jpiat
td2_tns [2016/03/29 17:00] (Version actuelle)
bvandepo [Configuration du timer 2 en générateur d'interruptions]
Ligne 10: 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 24: 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 45: Ligne 51:
  
 <ifauth @prof> <ifauth @prof>
 +===Solution:​===
 +<file cpp configtimer.cpp>​
 +void setupTimer2(unsigned char prescaler, unsigned int period){
   TCCR2A = 0;// set entire TCCR2A register to 0   TCCR2A = 0;// set entire TCCR2A register to 0
   TCCR2B = 0;// same for TCCR2B   TCCR2B = 0;// same for TCCR2B
   TCNT2  = 0;//​initialize counter value to 0   TCNT2  = 0;//​initialize counter value to 0
-  OCR2A = 124;+  OCR2A = period;
   // turn on CTC mode   // turn on CTC mode
   TCCR2A |= (1 << WGM21);   TCCR2A |= (1 << WGM21);
-  TCCR2B |= (1 << CS21); // config of prescaler+  TCCR2B |= prescaler & 0x7; // config of prescaler
   // enable timer compare interrupt   // enable timer compare interrupt
   TIMSK2 |= (1 << OCIE2A); ​   TIMSK2 |= (1 << OCIE2A); ​
 +}
 +</​file>​
 </​ifauth>​ </​ifauth>​
  
Ligne 60: 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 68: Ligne 79:
  
 <ifauth @prof> <ifauth @prof>
 +===Solution:​===
 +<file cpp adc1.cpp>​
   void setupADCPolling()   void setupADCPolling()
   {   {
- ADCSRA ​  = 1 << ADPS2 | 1 << ADPS1 | 1 << ADPS0 | 1 << ADEN:; // div 128, enabled +        ADCSRB=0;  
-        ADMUX    = 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 +  /*! \brief ADC Conversion Routine in single ended mode */ 
-   ​*  ​in single ended mode */ +  ​unsigned int readADCPolling(void)
-  ​void readADCPolling(void)+
   {   {
- ADCSRA ​ |= (1<<​ADSC);​ // Start ADC Conversion+  unsigned int result; 
 + ADCSRA ​ |= (1<<​ADSC);​ // Start ADC Conversion
  while((ADCSRA & (1<<​ADIF)) != 0x10); // Wait till conversion is complete  while((ADCSRA & (1<<​ADIF)) != 0x10); // Wait till conversion is complete
  result ​  = ADC;                         // Read the ADC Result  result ​  = ADC;                         // Read the ADC Result
- ADCSRA ​ |= (1 << ADIF); // Clear ADC Conversion Interrupt Flag+ ADCSRA ​ |= (1 << ADIF); // Clear ADC Conversion Interrupt Flag
        ​return result ;        ​return result ;
   }   }
 +  </​file>​
 </​ifauth>​ </​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 89: 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 136: 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.1426507765.txt.gz · Dernière modification: 2015/03/16 13:09 par jpiat