Beruflich Dokumente
Kultur Dokumente
Leçon N°9
LES TIMERS EN MIKROC
1. Principe de fonctionnement
Rôle : Réaliser une temporisation
Elément essentiel : Compteur qui s'incrémente à chaque front montant du signal qui lui est appliqué
:
Lorsque le compteur dépasse la valeur maximale qu'il peut contenir (par exemple : 256 pour
un compteur sur 8 bits), un drapeau (flag en anglais) se lève.
Ce drapeau a pour but d'indiquer au programme que le compteur a débordé (c'est à dire qu'il a
fini de compter). De la même manière que pour la boite aux lettres, c'est au programme de
rebaisser le drapeau pour recommencer un cycle de comptage (ça ne se fait pas tout seul !).
2. Méthodes de configuration
Un Timer doit pouvoir compter un temps défini par le programme (par exemple 1ms, 10ms, 50ms,
etc.). Pour cela, 2 paramètres peuvent être modifiés :
La fréquence du signal applique au compteur : Le compteur s'incrémentera ainsi plus ou
moins vite.
Le nombre d'impulsions à compter : Le drapeau se lève toujours lorsqu'il y a débordement, on
peut donc faire partir le compteur d'une valeur non nulle pour réduire le temps de comptage.
Modification de la fréquence du signal applique au compteur : le pré-diviseur (prescaler en anglais)
Mr Nizar TOUJENI 81
Microcontrôleurs Iset de Nabeul
Calcul du temps mis par le Timer pour faire lever son drapeau :
Mr Nizar TOUJENI 82
Microcontrôleurs Iset de Nabeul
Mr Nizar TOUJENI 83
Microcontrôleurs Iset de Nabeul
Mr Nizar TOUJENI 84
Microcontrôleurs Iset de Nabeul
permettant de tester la fin du comptage. Les bits 7, 6 et 5 seront vus lors du chapitre sur les
interruptions.
OPTION_REG : Nous venons de le voir ...
Exemple de programme
void tempo_timer0 ( void ); // tempo de 10ms avec le timer0
void init ( void ); // initialisation des périphériques
void main ( void )
{
init(); // initialisation des périphériques
while ( 1 ) // boucle infinie
{
PORTB.F1 = !PORTB.F1; // on change l'état de RB1
tempo_timer0(); // tempo de 10 ms
}
}
void tempo_timer0 ( void ) // tempo de 10ms avec le timer0
{
TMR0 = 100; // initialisation du registre de comptage
T0IF = 0; // initialisation du drapeau lié au timer0
while ( T0IF == 0 ); // attente de la levée du drapeau
}
void init ( void ) // initialisation des périphériques
{
TRISB = 0; // RB1 configuré en sortie
OPTION_REG = 0x85; // configuration du timer0 : pré-diviseur à 64
}
Mr Nizar TOUJENI 85
Microcontrôleurs Iset de Nabeul
Originalité de ce Timer
Le flag ne se lève pas systématiquement à chaque fin de comptage.
Existence d'un post-compteur.
Ce post-compteur peut prendre chaque valeur entière entre 1 et 16.
Exemple pour un post-compteur de 4 :
Mr Nizar TOUJENI 86
Microcontrôleurs Iset de Nabeul
Mr Nizar TOUJENI 87
Microcontrôleurs Iset de Nabeul
Exemple de programme
void tempo_timer2 ( void ); // tempo avec le timer2
void init ( void ); // initialisation des périphériques
void main ( void )
{
init(); // initialisation des périphériques
while ( 1 ) // boucle infinie
{
PORTB.F1 = !PORTB.F1; // on change l'état de RB1
tempo_timer2(); // tempo de 50 ms
}
}
void tempo_timer2 ( void ) // tempo avec le timer2
{
TMR2IF = 0; // initialisation du drapeau lié au timer2
while ( TMR2IF == 0 ); // attente de la levée du drapeau
}
void init ( void ) // initialisation des périphériques
{
TRISB = 0; // RB1 configuré en sortie
PR2 = 239; // Valeur définie de fin de comptage
T2CON = 0x66; // configuration du timer2
}
3.3. Le Timer1 du 16F877
Les particularités du Timer 1 sont :
Principe de fonctionnement similaire au Timer0
Le pré-compteur ne peut prendre que quatre valeurs : 1, 2, 4 ou 8.
Le compteur est un compteur 16 bits : Registre de comptage compose de deux registres de 8
bits (TMR1H et TMR1L).
Mr Nizar TOUJENI 88
Microcontrôleurs Iset de Nabeul
Mr Nizar TOUJENI 89
Microcontrôleurs Iset de Nabeul
La ligne RC1/T1OSI est aussi associée au Timer 1, mais ne joue pas de rôle dans le comptage
d'événements extérieurs.
Compte tenu de la remarque ci-dessus, il faut déconnecter la ligne RC1 / T1OSI en invalidant
la porte logique inverseuse.
bit T1OSCEN = 0
4.3. Timer 1 associe à un quartz
Il est possible de connecter un quartz sur le Timer 1 et de compter les impulsions de celui-ci
pour générer des temps plus precis comme par exemple pour créer une horloge de secondes,
minutes, heures ou un chronomètre.
Très utile pour gérer le mode sommeil du microcontrôleur.
En général, on prend un quartz dit d'”horloger” de 32768 Hz (on divise ensuite par 215 pour
avoir 1s).
T1OSCEN = 1
5. Exemples
Exemple 1 : RELAI
Dans ce projet la minuterie, sur la base de registre TMR0, est utilisée comme un compteur. L'entrée
de comptage est reliée à un bouton-poussoir Input de sorte que toute pression sur Input provoque
TMR0 à compter une impulsion. Lorsque le nombre d'impulsions correspond au nombre stocké dans
le registre nommé TEST, la valeur logique 1 (5V) apparaît sur le pin3 de PORTD. Cette tension
active un relais électromécanique, et ce bit est appelé « RELAI » dans le programme.
Mr Nizar TOUJENI 90
Microcontrôleurs Iset de Nabeul
Dans le registre de TEST est stocké un nombre de 5 pour cet exemple. Bien sûr, il peut être n'importe
quel nombre défini comme une constante. Par ailleurs, le microcontrôleur peut activer un autre
appareil au lieu de relais, tandis que le capteur peut être utilisé à la place du bouton-poussoir. Cet
exemple illustre l'une des applications les plus courantes du microcontrôleur dans l'industrie ; quand
quelque chose est effectué autant de fois que nécessaire, puis quelque chose d'autre doit être activé ou
désactivé, etc.
Code-source 1
void main()
{
char TEST = 5; // Constante TEST = 5
enum sortie {RELAI = 3}; // Constante RELAI = 3
ANSEL = 0; // Les E/S sont configurées en numériques
ANSELH = 0;
PORTA = 0; // Initialisation du porte A
TRISA = 0xFF; // Port A est configure en entrée
PORTD = 0; // Initialisation du PORTD
TRISD = 0b11110111; // Broche 3 du PORTD3 est configure en sortie
OPTION_REG.F5 = 1; // Compteur TMR0 reçoit des impulsions par la broche RA4
OPTION_REG.F3 = 1; // Taux de prédiviseur est de 1:1
TMR0 = 0; // Initialisation du compteur TMR0
do
{
if (TMR0 == TEST) PORTD.RELAI = 1;
// Est-ce que le nombre d’impulsion TMRO est égal à constante TEST?
// Nombre est égal à TEST. La broche RD3 est en 1 (RELAIS est active)
}
while (1); // Restez dans la boucle sans fin
}
Exemple 2. Registres TMR0 et TMR1 comme minuteries
Dans l'exemple précédent, le microcontrôleur ne fait rien entre des impulsions de comptage en
utilisant des boucles sans fin. Ces déchets du temps sont un luxe inadmissible et par conséquent une
autre méthode doit être appliquée. Considérons le schéma à microcontrôleur 16F887 de la figure 4
qui sera toujours le même pour réaliser les nouvelles fonctions.
Le fichier INTERRUP_TMR0.C du code-source 2 montre l’utilisation du registre TMRO avec pré
diviseur pour générer une interruption. Une fois que le registre TMR0 est « trop-plein » le routin
Mr Nizar TOUJENI 91
Microcontrôleurs Iset de Nabeul
d’interruption incrémente automatiquement la variable cnt par 1. Lorsque sa valeur atteint 400, le
PORTB est incrémenté de 1. L'ensemble de la procédure est « masqué », qui permet au
microcontrôleur de faire autre chose.
Code-source 2
unsigned cnt; // Définir la variable cnt
void interrupt( )
{
cnt++; // Interruption cause l’incrémentation par 1 de la variable cnt
TMR0 = 100; // Valeur initiale du TMR0
INTCON = 0x20; // Bit T0IE est positionné à 1, bit T0IF est en 0
}
void main()
{
OPTION_REG = 0x84; // Prédiviseur pour TMR0
ANSEL = 0; // Toutes les broches E/S sont configuré en digital
ANSELH = 0;
TRISB = 0; // PORTB est configuré en sortie
PORTB = 0x0; // Initialisation du PORTB
Mr Nizar TOUJENI 92
Microcontrôleurs Iset de Nabeul
Code-source 3
unsigned short cnt; // Définir la variable cnt
void interrupt()
{
cnt++ ; // Interruption cause l’incrémentation par 1 de la variable cnt
PIR1.TMR1IF = 0; // Remise à 0 bit TMR1IF
TMR1H = 0x80;
Mr Nizar TOUJENI 93
Microcontrôleurs Iset de Nabeul
Mr Nizar TOUJENI 94