ATmega328 – Configuration du TIMER1

Les principales caractéristiques de ce timer sont les suivantes :

  • Conception 16-bits ;
  • Deux sorties après comparaison indépendantes ;
  • Registres de sortie bufferisés (lecture stable pendant le comptage) ;
  • Une entrée de capture d’événement, avec suppression du bruit ;
  • Réinitialisation du timer à la détection de l’égalité ;
  • PWM sans déphasage ;
  • PWM à période variable ;
  • Générateur de fréquence ;
  • Compteur d’événements externes ;
  • 4 sources de d’interruption indépendantes.

Pour rappel, ci-dessous, le schéma des fonctions du TIMER1 ; il faut évidemment remplacer le n par 1.

Modulation en largeur d’impulsion (PWM)

C’est l’usage le plus courant de ce timer, c’est donc la configuration qui est proposée en premier ici.

Dans ce mode de fonctionnement, le timer compte de manière incrémentale de 0 (BOTTOM) à une valeur TOP, puis se réinitialise à la valeur BOTTOM. Lorsqu’une des valeurs de comparaison est franchie (OCR1A ou OCR1B), la sortie associée change d’état ; de même lorsque la valeur du compteur atteint BOTTOM. Ainsi les sorties produisent des signaux de fréquence fixe et de rapport cyclique proportionnel à la valeur de comparaison (OCR1x).

Valeur maximum (TOP) du compteur

Pour contrôler le fonctionnement du timer, il faut d’abord choisir la valeur maximum (TOP) que peut atteindre le compteur au moyen des modes indiqués ci-dessous ; cela donne aussi la précision de la modulation :

ModeFonctionnementDescriptionWGM13,12,11,10
5Fast PWM, 8 bitsCompte de 0 à 0x00FF0101
6Fast PWM, 9 bitsCompte de 0 à 0x01FF0110
7Fast PWM, 10 bitsCompte de 0 à 0x03FF0111
14Fast PWMCompte de 0 à ICR1 (OC1B1110
15Fast PWMCompte de 0 à OCR1A1111

Le numéro du mode doit être indiqué dans les registres TCCR1A et TCCR1B :

Registre TCCR1A :

Bit76543210
NomCOM1A1COM1A0COM1B1COM1B0--WGM11WGM10

Registre TCCR1B :

Bit76543210
NomICNC1ICES1-WGM13WGM12CS12CS11CS10

Horloge du compteur

Il faut ensuite paramétrer la source de l’horloge qui produit l’incrément du timer. En effet, le timer peut être cadencé, soit sur l’horloge interne, directe ou divisée, soit par une source externe appliquée à la broche T1. Le tableau suivant précise les valeurs à appliquer aux bits du registre TCCR1B en fonction de la source choisie :

CS12CS11CS10Description
000Pas de source (compteur arrêté)
001clkI/O (pas de division)
010clkI/O / 8 (pré-division)
011clkI/O / 64 (pré-division)
100clkI/O / 256 (pré-division)
101clkI/O / 1024 (pré-division)
110Source sur broche T1 ; sur front descendant
111Source sur broche T1 ; sur front montant

Registre TCCR1B :

Bit76543210
NomICNC1ICES1-WGM13WGM12CS12CS11CS10

Comportement des sorties

Enfin, il faut préciser le comportement attendu des broches de sortie (OC1A & OC1B) lors des changements d’état, à savoir :

COM1A1COM1A0Description
00Fonctionnement normal du port ; OC1A déconnectée
01Modes 14 et 15 : bascule de OC1A lors de la détection d’égalité ;
Autres modes : fonctionnement normal du port ; OC1A déconnectée
10OC1A = 0 lors de la détection d’égalité ;
OC1A = 1 lorsque le compteur passe à 0 (BOTTOM)
(mode non-inversé)
11OC1A = 1 lors de la détection d’égalité ;
OC1A = 0 lorsque le compteur passe à 0 (BOTTOM)
(mode inversé)
COM1B1COM1B0Description
00Fonctionnement normal du port ; OC1B déconnectée
01 Fonctionnement normal du port ; OC1B déconnectée
10OC1B = 0 lors de la détection d’égalité ;
OC1B = 1 lorsque le compteur passe à 0 (BOTTOM)
(mode non-inversé)
11OC1B = 1 lors de la détection d’égalité ;
OC1B = 0 lorsque le compteur passe à 0 (BOTTOM)
(mode inversé)

Les modes de fonctionnement des broches de sortie doivent être indiqués dans le registre TCCR1A :

Bit76543210
NomCOM1A1COM1A0COM1B1COM1B0--WGM11WGM10

Interruptions

Il est aussi possible d’utiliser des interruptions qui sont déclenchées lors des phases d’égalité du compteur avec les registres de comparaison (OCR1A & OCR1B) ou lorsque le compteur se réinitialise de TOP à BOTTOM (overflow).

2 Thoughts to “ATmega328 – Configuration du TIMER1”

  1. Bonjour, Je découvre les microcontrôleurs ATméga328P. J’ai déjà utilisé la carte arduino uno. Je souhaite m’affranchir de l’interface implémenté et programmer directement en assembleur AVR mes projets pour mieux maîtriser le code. Je recherche un exemple de programme simple me donnant la structure de base pour démarrer un projet. J’aimerai de l’aide pour savoir comment déclarer les vecteurs d’interruptions non utilisés et comment valider une interruption sur une pin d’entrée sur un front montant ou descendant. Je dois aussi connaître la commande assembleur me permettant d’utiliser l’horloge externe avec un quartz. Donc programmer le fusibles internes en conséquences. Peut-être avez-vous quelques éléments de réponses à mes questionnements. Bien à vous…

    1. Bonsoir,
      Je ne suis pas convaincu que le passage par l’assembleur soit une bonne solution. Le langage C/C++ de l’IDE Arduino peut très bien faire le job même avec son bootloader. Par contre il est certain qu’il faut faire très attention au code et à l’utilisation des données, la pile (stack) ou le tas (heap). Il est toutefois possible de demander au compilateur de générer le code ASM pour le “regarder”, mais les optimisations peuvent aussi de faire en regardant la taille du code et des données en changeant la manière de rédiger le code. Tous les vecteurs d’interruption sont accessibles dans le code C et la configuration des fusibles est aussi accessible par l’IDE de l’Arduino.

      Marc

Comments are closed.