Micro contrôleurs AVR/Le Timer 2

Début de la boite de navigation du chapitre

Nous regroupons dans ce chapitre les quelques informations utiles concernant le timer 2. C'est un timer très proche du timer 0 : il est aussi sur 8 bits.

Le Timer 2
Icône de la faculté
Chapitre no 6
Leçon : Micro contrôleurs AVR
Chap. préc. :Le Timer 1
Chap. suiv. :Les communications en tout genre
fin de la boite de navigation du chapitre
En raison de limitations techniques, la typographie souhaitable du titre, « Micro contrôleurs AVR : Le Timer 2
Micro contrôleurs AVR/Le Timer 2
 », n'a pu être restituée correctement ci-dessus.


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 est mis à un automatiquement par le matériel. Ce ne sera pas la matériel qui le mettra à 0 s'il n'y a pas d'interruptions. C'est à vous programmeur de le faire ! Mais pour le faire il vous faut écrire un 1 dans ce bit b0 !

Les habituels bits de configuration de la division se trouvent dans le registre TCCR2B et fonctionnent exactement comme pour timer 0.

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.

Génération de signaux

modifier

Attente passive du drapeau

modifier

Les bits appelés drapeaux (flag en anglais) sont spéciaux : ils sont mis à 1 par le matériel mais doivent être relis à 0 par le programmeur (VOUS donc). Et comble de complexité la mise à 0 du bit correspondant se fait par une mise à 1 !

En utilisant une interruption

modifier

L'attente passive de la section précédente peut être évitée à l'aide des interruptions. On imagine un programme qui fait des tas de choses mais qui sera interrompu régulièrement par un timer.

 
La comparaison avec le Timer 2 (8 bits)

Comme d'habitude, la réalisation de l'interruption se fait par la transmission du front montant de TOV2 dans l'ellipse rouge. Et pour ce faire, il faut naturellement mettre TOIE2 de TIMSK2 à 1, ainsi que I de SREG.

Pour être complet, la mise à 1 de I se fait par un simple "sei();" en C. Son objectif est d'autoriser de manière générale les interruptions. Les bits de TIMSK2 sont manipulés de manière standard.

Exemple d'interruption

modifier

Vous disposez d'un shield permettant la commande de deux afficheurs. Celui-ci est câblé comme ceci :

Segment pt g f e d c b a
Arduino Pin 11 9 10 8 7 6 12 13
Port PB3 PB1 PB2 PB0 PD7 PD6 PB4 PB5

D'autre part la broche PD4 est responsable de la commutation des deux afficheurs. Réaliser une interruption d'affichage et un compteur en programme principal capable de compter sur une variable 8 bits en décimal.

Voici une solution possible qu’il faudra adapter à votre shield :

// OK UNO + shield IUT
#define F_CPU 16000000UL
#define __DELAY_BACKWARD_COMPATIBLE__ 
#include <util/delay.h>
 
// deux ports sont utilisés dans le câblage du shield 
const uint8_t affPortB[10]={0b00110101,0b00010000,0b00110011,0b00110010,0b00010110,0b00100110,0x27,0x30,0x37,0x36};
const uint8_t affPortD[10]={0b11000000,0b01000000,0b10000000,0b11000000,0b01000000,0b11000000,0xC0,0x40,0xC0,0xC0};

volatile unsigned char mux=0; 
volatile uint8_t n=0;

ISR(TIMER2_OVF_vect) {
   // changer d'afficheur à chaque interruption
   mux++;
   if ((mux & 0x01)==0x00) {
     PORTB = affPortB[n & 0x0F];
     PORTD = affPortD[n & 0x0F];
     PORTD |= 0x10; // afficheur unité
   } else {
     PORTB = affPortB[(n & 0xF0)>>4];
     PORTD = affPortD[(n & 0xF0)>>4];
     PORTD &= ~0x10; // afficheur dizaine
   }
}

int main() { 
// config e/s
   DDRB = 0x3F;
   DDRD = 0xD0;
// choix du pré-diviseur par 1024
  TCCR2B |= (1<<CS22);
  TCCR2B |= (1<<CS21);
  TCCR2B |= (1<<CS20);
// Acquittement du drapeau TOV2
  TIFR2 |= 1<<TOV2;
// autorisation de l'interruption débordement timer 2
  TIMSK2 |= (1<<TOIE2);
// autorisation générale des interruptions
  sei();
// debut de la boucle infinie
  while(1) {
// debut du comptage BCD
     n++;
     if ((n&0x0F)>0x09)
       n = n+6;
     if ((n&0xF0)> 0x90)
       n = n+0x60;
// attente passive
     _delay_ms(1000);
   }
}


Sans interruption et sans attente passive : le matériel fait tout

modifier

Voici la documentation correspondante sous forme de schéma (ci-contre).

 
La comparaison avec le Timer 2 (8 bits)

Ce mode de fonctionnement s’appelle la comparaison. L’idée générale est que lorsque le timer 2 (TCNT2) arrive à la même valeur que celle qui est contenue dans un registre (OCR2A ou OCR2B) une logique interne est capable de changer (ou pas) une sortie qui s’appelle OC2A ou OC2B.

Ce mode est essentiellement géré par les deux bits COM2A1 et COM2A0 comme indiqué dans le tableau ci-dessous :

Mode non PWM pour la comparaison
COM2A1 COM2A0 Description
0 0 Opération Normale PORT, OC2A déconnecté
0 1 Bascule OC2A sur la comparaison
1 0 Mise à 0 de OC2A sur la comparaison
1 1 Mise à 1 de OC2A sur la comparaison

Generation de signal MLI

modifier

La Modulation de Largeur d'Implulsion ou MLI permet de faire varier des intensités lumineuses ou des vitesses de rotation de moteur.

Ce mode est géré par les bits WGM22, WGM21 et WGM20 en suivant le tableau suivant :

Description des bits pour les modes de fonctionnement du timer 2
Mode WGM22 WGM21 WGM20 Mode de fonctionnement Bas si Mise à jour de OCRAx si Drapeau TOV2 positionné si
0 0 0 0 Normal 0XFF immédiatement MAX
1 0 0 1 PWM à phase correcte OXFF TOP BOTTOM
2 0 1 0 CTC OCR2A immédiatement MAX
3 0 1 1 PWM rapide 0XFF BOTTOM MAX
4 1 0 0 Reservé - - -
5 1 0 1 PWM à phase correcte OCR2A TOP BOTTOM
6 1 1 0 Reservé - - -
7 1 1 1 PWM rapide OCR2A BOTTOM TOP

Attention : ces trois bits n'appartiennent pas au même registre comme le montre le schéma ci-dessous !

 
La documentation (presque) complète du Timer 2 (8 bits)

Comme la figure ci-dessus ne le documente pas, nous donnons maintenant les modes de générations de signaux en mode PWM rapide.

Mode PWM rapide
COM2A1 COM2A0 Description
0 0 Opération Normale de PORT, OC2A déconnecté
0 1 WGM22 = 0: Opération Normale de PORT, OC2A déconnecté, WGM22 = 1: Bascule OC2A sur la comparaison
1 0 Mise à 0 de OC2A sur la comparaison et à 1 sur overflow (MLI non inversée)
1 1 Mise à 1 de OC2A sur la comparaison et à 0 sur l'overflow (MLI inversée)