Introduction aux Timers

Transcription

Introduction aux Timers
Introduction aux Timers
La gestion du temps qui s'écoule peut devenir très difficile avec un microcontrôleur lorsque c'est le
programme seul qui doit s'en occuper. La technique qui consiste à exécuter des instructions pour
compter le temps peut fonctionner dans des cas simples, par exemple avec un attente active du
type :
volatile int i ; for (i=0 ; i<1000 ; i++) {}
Mais dès que le programme doit s'occuper de plusieurs tâches en même temps, une gestion précise
du temps devient impossible.
Les fabricants ajoutent donc aux microcontrôleurs des compteurs-minuteurs, qu'on appelle
généralement des Timers. Ils facilitent la gestion du temps, en permettant en particulier :
– de connaître le temps qui s'écoule, un peu comme une horloge
– d'être averti après qu'un certain temps se soit écoulé (output compare)
– de saisir le moment exact d'un événement (input capture)
On utilise souvent les Timers pour générer des signaux PWM.
Voici un schéma qui donne l'architecture d'un Timer :
On y trouve :
–
–
–
–
–
–
un compteur binaire. Il peut s'agir d'un compteur 8 bits, 16 bits ou 32 bits
un horloge qui commande ce compteur. Elle est programmable : il est possible de choisir la
source de l'horloge (par exemple l'horloge principale du microcontrôleur ou une horloge
externe) ainsi qu'une pré-division de cette horloge (par exemple par 1, 2, 4 ou 8)
un fanion qui indique le dépassement de capacité du compteur, appelé Overflow
un registre de capture/comparaison, relié au compteur par un comparateur d'égalité
un fanion de comparaison
des fanions d'activation des interruptions pour l'Overflow et la comparaison.
Le diagramme ci dessous donne un diagramme des temps d'un Timer. On y voit l'évolution de la
valeur du Timer et les événements associés : la détection d'un dépassement de capacité (overflow)
et la comparaison avec une valeur, qui peut changer au cours du temps.
2013 Pierre-Yves Rochat, [email protected], version du 28/04/2013, PROVISOIRE !
La programmation des Timers se fait presque toujours avec des interruptions. Voici les étapes
généralement nécessaires pour mettre en œuvre un Timer :
–
–
–
–
choix de l'horloge et de la prédivision
autorisation de l'interruption ou des interruptions (par exemple overflow et comparaison)
écriture de la valeur de comparaison si elle est utilisée
autorisation générale des interruptions
Voici un exemple simple de mise en œuvre d'un Timer sur un MSP430. Il permet de déclencher une
action à intervalle régulier.
#include <msp430g2553.h>
void main(void) {
WDTCTL = WDTPW + WDTHOLD; // Stop Watchdog Timer
P1DIR |= (1<<0); // P1.0 en sortie
CCTL0 = CCIE; // autorisation de l'interruption de comparaison
CCR0 = 50000; // délai initial
TACTL = TASSEL_2 + MC_2; // Choix de l'horloge SMCLK; comptage 0 à max
_BIS_SR(IE); // Autorisation générale des interruptions
while (1) { (/ boucle principale, vide
}
}
// Timer A0 interrupt service routine
#pragma vector=TIMER0_A0_VECTOR
__interrupt void Timer_A (void) {
P1OUT ^= (1<<0); // Toggle P1.0 (inversion)
CCR0 += 50000; // Nouvelle valeur de comparaison, offset ajouté à CCR0
}
2013 Pierre-Yves Rochat, [email protected], version du 28/04/2013, PROVISOIRE !