Cours:InfoS2 tdGenerationSignal : Différence entre versions

De troyesGEII
Aller à : navigation, rechercher
(Configuration du timer 2 en {{Rouge|fast PWM}})
 
(9 révisions intermédiaires par le même utilisateur non affichées)
Ligne 8 : Ligne 8 :
  
  
=Cahier des charges=
+
=Principe=
  
 +
[[Image:mliGenerationSinus.png|300px]]
  
=Configuration du timer 2 en {{Rouge|fast PWM}}=
+
*https://fr.wikipedia.org/wiki/Modulation_de_largeur_d%27impulsion
 +
*https://www.f-legrand.fr/scidoc/docmml/sciphys/arduinodue/ondepwm/ondepwm.html
 +
 
 +
=génération du signal=
 +
==Configuration du timer 2 en {{Rouge|fast PWM}}==
  
 
On utilise le Timer 2 pour générer un signal MLI qui sera filtré par un filtre passe-bas passif.
 
On utilise le Timer 2 pour générer un signal MLI qui sera filtré par un filtre passe-bas passif.
Ligne 18 : Ligne 23 :
  
 
{{Question|En utilisant les différents tableaux dans la datasheet :}}
 
{{Question|En utilisant les différents tableaux dans la datasheet :}}
*configurer le timer 2 en mode 7 : Fast PWM avec valeur TOP = OCR2A
+
*configurer le timer 2 en {{Rouge|mode 7}} : Fast PWM avec valeur TOP = OCR2A
*sachant que Fmli = Fcpu / (P . (OCR2A+1)) et on souhaite une fréquence de xx kHz
+
*sachant que Fmli = Fcpu / (P . (OCR2A+1)) et on souhaite une fréquence de {{Rouge|160 kHz}}
**choisir et configurer une valeur de Prédiviseur
+
**choisir et configurer une valeur de {{Rouge|Prédiviseur}}
**choisir une valeur pour OCR2A
+
**choisir une valeur pour {{Rouge|OCR2A}}
*le prédiviseur (qui changera la Fmli )
+
*la configuration des bits {{Rouge|COM2??}} sachant que nous utilisons le mode fast PWM sur la broche {{Rouge|OC2B}}
*la configuration des bits COMxAx sachant que nous utilisons le mode fast PWM
+
 
! Fcpu = 8 MHz !
 
  
 
{{Question|Compléter en conséquence le programme avec la configuration du timer :}}
 
{{Question|Compléter en conséquence le programme avec la configuration du timer :}}
 
<source lang=cpp>
 
<source lang=cpp>
 +
#define F_CPU 16000000ul
 +
#include <avr/io.h>
 +
#include <util/delay.h>
 +
#include <avr/interrupt.h>
 +
 
int main()
 
int main()
 
{
 
{
   // configuration des sorties
+
  // sortie utilisee pour la synchronisation de l'oscillo
 +
  DDRB |=(1<<PB2);
 +
   // configuration de la sortie
  
   // timer en mode fast PWM (mode 3)
+
   // timer en mode fast PWM (mode 7)
  
 
   // valeur du prediviseur
 
   // valeur du prediviseur
  
   // génération de la sortie par le timer
+
   // génération de la sortie sur OC2B par le timer
  
  // rapport cyclique
 
 
    
 
    
 
   while(1)
 
   while(1)
 
   {
 
   {
     // on peut changer le rapport cyclique régulièrement
+
     // incrémenter régulièrement le rapport cyclique (attention à la valeur max)
     _delay_ms(500);
+
 
 +
 
 +
    // afin de synchroniser, on change l'état de PB2 à chaque période
 +
    if ( OCR2B==99) PORTB^=(1<<PB2);
 +
     _delay_ms(100);
 
   }
 
   }
 
}
 
}
 
</source>
 
</source>
 +
 +
==génération d'un signal sinusoïdal==
 +
 +
{{Question|modifier votre programme pour générer un signal sinusoïdal en utilisant la table de sinus suivante :}}
 +
 +
<source lang=cpp>
 +
const uint8_t tabSinus[36]={50, 59, 67, 75, 81, 88, 92, 96, 98, 99, 98, 96, 92, 88, 81, 75, 67, 59, 50, 41, 33, 25, 19, 12, 8, 4, 2, 1, 2, 4, 8, 12, 19, 26, 33, 41};
 +
uint8_t angle=0;
 +
</source>
 +
 +
*les valeurs successives de "rapport cyclique" sont les valeurs du tableau
 +
*la fréquence de la sinusoïde dépend de la vitesse de lecture des valeurs
 +
**sur l'oscilloscope simulIde, regarder la fréquence du signal de synchronisation ! (rapport 2 sur les fréquences)
 +
**calculer la valeur du delay pour avoir une fréquence sur signal sinusoïdal de 440Hz
 +
 +
=Suppression du "delay"=
 +
 +
On souhaite utiliser un Timer pour modifier régulièrement la valeur du rapport cyclique. Le principe sera le suivant :
 +
 +
*On utilise le Timer1 (16 bits)
 +
*On place le timer en mode CTC (datasheet p133)
 +
*On prendre la valeur 1 comme prédiviseur (datasheet p134)
 +
*Choisir la valeur de OCR1A pour avoir une interruption toutes les 63µs (sinusoïde à 440Hz)
 +
*On autorise l'interruption de comparaison OCIE1A (p137)
 +
*La routine d'interruption sera de la forme suivante :
 +
<source lang=cpp>
 +
ISR(TIMER1_COMPA_vect)
 +
{
 +
  // déclarer une variable static sur 8 bits qui sera la valeur d'angle (entre 0 et 35)
 +
  ...
 +
  // changer la valeur du rapport cyclique en utilisant le tableau
 +
  OCR2B = ...;
 +
  // incrémenter la valeur de l'angle, en ne dépassant pas 35 !
 +
  ...
 +
}
 +
</source>
 +
 +
Vous pouvez utiliser ce fichier :
 +
 +
*** [[Media:CalculTimer.ods|{{Rouge|feuille de calcul pour les TIMERS}}]] ***
 +
 +
 +
{{Question|Faire les modifications et valider le fonctionnement}}

Version actuelle datée du 12 mars 2024 à 23:33

Atmega328pPinout.jpeg

Fiche résumé

Retour à la liste des Tds/Tps

Éléments de correction

simuler avec simulIDE

Pensez à mettre sur la 1ère ligne de votre code :
// Compiler: Avrgcc device: nomDuMicrocontroleur


fichier pour simuler avec simulIDE : infouc_TdGenerationSignal.sim1
datasheet aTmega328p


Principe

MliGenerationSinus.png

génération du signal

Configuration du timer 2 en fast PWM

On utilise le Timer 2 pour générer un signal MLI qui sera filtré par un filtre passe-bas passif.

Todo.jpg Chercher dans la datasheet du µcontroleur (lien ci dessus) la section décrivant ce périphérique et plus particulièrement les pages donnant la descriptions des registres

Question.jpg En utilisant les différents tableaux dans la datasheet :

  • configurer le timer 2 en mode 7 : Fast PWM avec valeur TOP = OCR2A
  • sachant que Fmli = Fcpu / (P . (OCR2A+1)) et on souhaite une fréquence de 160 kHz
    • choisir et configurer une valeur de Prédiviseur
    • choisir une valeur pour OCR2A
  • la configuration des bits COM2?? sachant que nous utilisons le mode fast PWM sur la broche OC2B


Question.jpg Compléter en conséquence le programme avec la configuration du timer :

#define F_CPU 16000000ul
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>

int main()
{
  // sortie utilisee pour la synchronisation de l'oscillo
  DDRB |=(1<<PB2);
  // configuration de la sortie

  // timer en mode fast PWM (mode 7)

  // valeur du prediviseur

  // génération de la sortie sur OC2B par le timer

  
  while(1)
  {
    // incrémenter régulièrement le rapport cyclique (attention à la valeur max)


    // afin de synchroniser, on change l'état de PB2 à chaque période
    if ( OCR2B==99) PORTB^=(1<<PB2);
    _delay_ms(100);
  }
}

génération d'un signal sinusoïdal

Question.jpg modifier votre programme pour générer un signal sinusoïdal en utilisant la table de sinus suivante :

const uint8_t tabSinus[36]={50, 59, 67, 75, 81, 88, 92, 96, 98, 99, 98, 96, 92, 88, 81, 75, 67, 59, 50, 41, 33, 25, 19, 12, 8, 4, 2, 1, 2, 4, 8, 12, 19, 26, 33, 41};
uint8_t angle=0;
  • les valeurs successives de "rapport cyclique" sont les valeurs du tableau
  • la fréquence de la sinusoïde dépend de la vitesse de lecture des valeurs
    • sur l'oscilloscope simulIde, regarder la fréquence du signal de synchronisation ! (rapport 2 sur les fréquences)
    • calculer la valeur du delay pour avoir une fréquence sur signal sinusoïdal de 440Hz

Suppression du "delay"

On souhaite utiliser un Timer pour modifier régulièrement la valeur du rapport cyclique. Le principe sera le suivant :

  • On utilise le Timer1 (16 bits)
  • On place le timer en mode CTC (datasheet p133)
  • On prendre la valeur 1 comme prédiviseur (datasheet p134)
  • Choisir la valeur de OCR1A pour avoir une interruption toutes les 63µs (sinusoïde à 440Hz)
  • On autorise l'interruption de comparaison OCIE1A (p137)
  • La routine d'interruption sera de la forme suivante :
ISR(TIMER1_COMPA_vect)
{
  // déclarer une variable static sur 8 bits qui sera la valeur d'angle (entre 0 et 35)
  ...
  // changer la valeur du rapport cyclique en utilisant le tableau
  OCR2B = ...;
  // incrémenter la valeur de l'angle, en ne dépassant pas 35 !
  ...
}

Vous pouvez utiliser ce fichier :

*** feuille de calcul pour les TIMERS ***


Question.jpg Faire les modifications et valider le fonctionnement