Cours:XR207 tp digicode : Différence entre versions

De troyesGEII
Aller à : navigation, rechercher
 
Ligne 2 : Ligne 2 :
  
 
[[Cours:TPS_2103_tp3_corrige|{{Vert|<big>'''Éléments de correction'''</big>}}]]
 
[[Cours:TPS_2103_tp3_corrige|{{Vert|<big>'''Éléments de correction'''</big>}}]]
 +
 +
 +
 +
 +
 +
={{Rouge|Complément au [[Cours:TPS_2103_tp2|TP précédent] : Mesure de temps d'exécution}}=
 +
 +
Nous allons dans cette partie mesurer le temps d'exécution de certaines fonctions Arduino, et se rendre compte de l'une de leur principale limite.
 +
 +
Le temps écoulé sera mesuré à l'aide du {{Rouge|Timer 2}}.
 +
 +
Le principe est le suivant :
 +
*Initialiser le timer
 +
*Répéter plusieurs fois l'instruction souhaitée
 +
*Observer la valeur du timer
 +
*Afficher cette valeur
 +
=={{Bleu|Le timer 2 et ses registres (sans interruption)}}==
 +
[[Fichier:AVR_Timer2.png|thumb|500px|Documentation simple du Timer 2 (8 bits)]]
 +
Voici ci-contre, avec les conventions schématiques habituelles, le schéma de fonctionnement du timer 2.
 +
 +
On distingue ainsi le bit b0 du registre '''TIFR2''' appelé '''TOV2''' qui permet de détecter un débordement du timer. Pour plus de précisions, référez-vous au td sur le sujet !
 +
 +
Les habituels bits de configuration de la division se trouvent dans le registre '''TCCR2B''' et fonctionnent exactement comme pour les autres timers.
 +
 +
Le registre '''ASSR''' sert à choisir la source de l'horloge du timer 2. Pour nous, sauf mention contraire, ce sera toujours le quartz. Ce registre doit être configuré dans ce mode de fonctionnement par défaut.
 +
 +
=={{Bleu|Configuration des entrées/sorties}}==
 +
 +
Nous souhaitons ici évaluer le temps mis par la fonction [http://arduino.cc/en/Reference/pinMode {{Rouge|pinMode()}}].
 +
 +
L'affichage du résultat sera tout simplement transmis sur la liaison série en utilisant les fonctions suivantes :
 +
*Serial.begin(debit)
 +
*Serial.print("valeur = ")
 +
*Serial.println(valeur,DEC)
 +
 +
{{Question|Compléter le programme suivant en choisissant les bonnes valeurs pour évaluer le temps d'exécution de pinMode()}}
 +
<source lang=c>
 +
void setup()
 +
{
 +
  // Variables éventuelles
 +
 +
  // Initialisation du port série
 +
  Serial.begin(9600);
 +
 +
  // Configuration du timer 2 : Attention, chaque bit doit être configuré à '0' ou '1'
 +
  TCCR2A ??? (1<<WGM20); // mettre à 0
 +
  TCCR2A ??? (1<<WGM21); // mettre à 0
 +
 +
  TCCR2B ??? (1<<WGM22); // mettre à 0
 +
// choix du pré-diviseur :
 +
  TCCR2B ??? (1<<CS22);
 +
  TCCR2B ??? (1<<CS21);
 +
  TCCR2B ??? (1<<CS20);
 +
 +
  // Initialisation du Timer : acquittement et valeur de départ
 +
  TIFR2|=1<<TOV2;
 +
 +
}
 +
 +
void loop() {
 +
  TCNT2=0; // timer2 mis à zéro
 +
 +
//********** debut du calcul dont on veut mesurer la durée
 +
  for (i=0;i<100;i++) // Le nombre d'itérations peut/doit être adapté !
 +
  {
 +
    // Fonction à évaluer : il est intéressant de répéter la fonction plusieurs fois
 +
    pinMode(6,OUTPUT);
 +
  }
 +
//********* fin du calcul dont on veut mesurer la durée
 +
 
 +
  // Récupérer la valeur du timer et l'afficher seulement si le timer n'a pas débordé !!!
 +
 +
  // envoyer dans liaison série
 +
 +
  delay(500);
 +
}
 +
</source>
 +
 +
 +
'''Attention ! ''' Ne prenez pas ce que vous donne le timer pour argent comptant. Cette valeur doit avoir certaines propriétés :
 +
* ne pas être accompagnée d'un débordement de '''TCNT2'''. Vous seriez donc très inspiré d'écrire la valeur du flag '''TOV2''' avec la liaison série en plus de la valeur de temps
 +
* augmenter lorsqu'on augmente le nombre de boucles exécutées sur l'instruction testée (autre manière de dire les choses, on double le temps si on double le nombre de boucles).
 +
 +
Ce travail nécessite dons un peu de soin et beaucoup d'essais pour trouver la bonne valeur de la division dans le pré-diviseur à choisir. Il peut être utile de mettre les tests dans loop() pour prendre son temps pour ouvrir la liaison série.
 +
 +
 +
{{Question|Comparer en déclarant une sortie directement en configurant le registre DDRx}}
 +
 +
=={{Bleu|Valeur de sortie}}==
 +
 +
Si la fonction pinMode() est d'importance, sa durée d'exécution ne l'est pas forcément puisque la plupart du temps elle n'est exécutée qu'une seule fois.
 +
 +
Allons donc un peu plus loin dans la manipulation des ports en modifiant l'état d'une sortie (pin 6 arduino ou PD6).
 +
 +
{{Question|Évaluer la durée d'exécution du code suivant :}}
 +
 +
<source lang=c>
 +
//void setup()
 +
//{
 +
  pinMode(6,OUTPUT);
 +
  for (char i=0;i<10;i++)
 +
  {
 +
    digitalWrite(6,0);
 +
    digitalWrite(6,1);
 +
  }
 +
 
 +
//}
 +
 +
//void loop()
 +
//{
 +
//}
 +
</source>
 +
 +
{{Question|Écrire le même code en utilisant directement les registres ad-hoc et comparer les vitesses d'exécution.}}

Version du 12 avril 2015 à 17:26

Retour à la liste des Tps

Éléments de correction



{{Rouge|Complément au [[Cours:TPS_2103_tp2|TP précédent] : Mesure de temps d'exécution}}

Nous allons dans cette partie mesurer le temps d'exécution de certaines fonctions Arduino, et se rendre compte de l'une de leur principale limite.

Le temps écoulé sera mesuré à l'aide du Timer 2.

Le principe est le suivant :

  • Initialiser le timer
  • Répéter plusieurs fois l'instruction souhaitée
  • Observer la valeur du timer
  • Afficher cette valeur

Le timer 2 et ses registres (sans interruption)

Documentation simple du Timer 2 (8 bits)

Voici ci-contre, avec les conventions schématiques habituelles, le schéma de fonctionnement du timer 2.

On distingue ainsi le bit b0 du registre TIFR2 appelé TOV2 qui permet de détecter un débordement du timer. Pour plus de précisions, référez-vous au td sur le sujet !

Les habituels bits de configuration de la division se trouvent dans le registre TCCR2B et fonctionnent exactement comme pour les autres timers.

Le registre ASSR sert à choisir la source de l'horloge du timer 2. Pour nous, sauf mention contraire, ce sera toujours le quartz. Ce registre doit être configuré dans ce mode de fonctionnement par défaut.

Configuration des entrées/sorties

Nous souhaitons ici évaluer le temps mis par la fonction pinMode().

L'affichage du résultat sera tout simplement transmis sur la liaison série en utilisant les fonctions suivantes :

  • Serial.begin(debit)
  • Serial.print("valeur = ")
  • Serial.println(valeur,DEC)

Question.jpg Compléter le programme suivant en choisissant les bonnes valeurs pour évaluer le temps d'exécution de pinMode()

void setup()
{
  // Variables éventuelles

  // Initialisation du port série
  Serial.begin(9600);

  // Configuration du timer 2 : Attention, chaque bit doit être configuré à '0' ou '1'
  TCCR2A ??? (1<<WGM20); // mettre à 0
  TCCR2A ??? (1<<WGM21); // mettre à 0

  TCCR2B ??? (1<<WGM22); // mettre à 0
// choix du pré-diviseur :
  TCCR2B ??? (1<<CS22);
  TCCR2B ??? (1<<CS21);
  TCCR2B ??? (1<<CS20);
 
  // Initialisation du Timer : acquittement et valeur de départ
  TIFR2|=1<<TOV2;

}

void loop() {
  TCNT2=0; // timer2 mis à zéro

//********** debut du calcul dont on veut mesurer la durée 
  for (i=0;i<100;i++) // Le nombre d'itérations peut/doit être adapté !
  {
    // Fonction à évaluer : il est intéressant de répéter la fonction plusieurs fois
    pinMode(6,OUTPUT);
  }
//********* fin du calcul dont on veut mesurer la durée
  
  // Récupérer la valeur du timer et l'afficher seulement si le timer n'a pas débordé !!!

  // envoyer dans liaison série

  delay(500);
}


Attention ! Ne prenez pas ce que vous donne le timer pour argent comptant. Cette valeur doit avoir certaines propriétés :

  • ne pas être accompagnée d'un débordement de TCNT2. Vous seriez donc très inspiré d'écrire la valeur du flag TOV2 avec la liaison série en plus de la valeur de temps
  • augmenter lorsqu'on augmente le nombre de boucles exécutées sur l'instruction testée (autre manière de dire les choses, on double le temps si on double le nombre de boucles).

Ce travail nécessite dons un peu de soin et beaucoup d'essais pour trouver la bonne valeur de la division dans le pré-diviseur à choisir. Il peut être utile de mettre les tests dans loop() pour prendre son temps pour ouvrir la liaison série.


Question.jpg Comparer en déclarant une sortie directement en configurant le registre DDRx

Valeur de sortie

Si la fonction pinMode() est d'importance, sa durée d'exécution ne l'est pas forcément puisque la plupart du temps elle n'est exécutée qu'une seule fois.

Allons donc un peu plus loin dans la manipulation des ports en modifiant l'état d'une sortie (pin 6 arduino ou PD6).

Question.jpg Évaluer la durée d'exécution du code suivant :

//void setup()
//{
  pinMode(6,OUTPUT);
  for (char i=0;i<10;i++)
  {
    digitalWrite(6,0);
    digitalWrite(6,1);
  }
  
//}

//void loop()
//{
//}

Question.jpg Écrire le même code en utilisant directement les registres ad-hoc et comparer les vitesses d'exécution.