Vous êtes sur la page 1sur 13

Tp0

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)
Exemple : pour compter 4 fois moins vite
Modification du nombre d'impulsions à compter
_ Si le compteur démarre à 0, il mettra beaucoup de temps à atteindre sa valeur maximale.
_ Pour réduire le temps de comptage, on peut donc charger une valeur initiale non nulle dans le
compteur.
_ Exemple : Valeur initiale égale à 250

3. Les Timers du PIC 16F877


Composition générale d'un Timer sur un microcontrôleur PIC :

Calcul du temps mis par le Timer pour faire lever son drapeau :

- Les Timers sont internes au microcontrôleur.


-Le 16F877 en compte 3 :
– Timer0 et Timer2 sur 8 bits
– Timer1 sur 16 bits
3.1. Le Timer0 du 16F877
Composition du Timer0
- Le pré-diviseur peut prendre une valeur parmi la liste suivante : 1, 2, 4, 8, 16, 32, 64, 128 ou
256.
-La valeur initiale peut prendre n'importe quelle valeur entière comprise entre 0 et 255.

Calcul du temps maximum


- Pour que le drapeau se lève le plus tard possible, il faut que la fréquence du signal applique
aucompteur soit la plus faible possible. Il faut donc configurer le pré-diviseur le plus grand :
256.

- Il faut également faire démarrer le compteur avec la valeur la plus petite possible pour qu'il
compte le nombre d'impulsion le plus grand : valeur initiale = 0.

Calcul d'un temps de 10ms


Registre de configuration du Timer0 : OPTION_REG

Registres associés au Timer0


-TMR0 : c'est le registre de comptage. C'est donc dans ce registre que nous allons rentrer
la valeur de départ de notre compteur.
- INTCON : seuls les bits 7, 6, 5 et 2 sont utiles pour le Timer 0 (ce sont les seuls non
grises).
nous ne nous intéresserons qu'au bit 2 appelé T0IF et qui correspond au flag 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 ...
3.2 Le Timer2 du 16F877

- Il est légèrement diffèrent du Timer 0 puisque le début de comptage est en principe


0x00 et que la fin de comptage est la valeur à entrer.
- Il possède comme le Timer 0 un pré-compteur fixe et un pré-compteur variable (3
valeurs possibles : 1, 4 et 16). C'est aussi un compteur 8 bits.

Calcul de la durée de comptage


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 :

La temporisation max de ce Timer est donc :


TMAX = 16 * 4,096 ms soit 65,536 ms
La formule permettant de calculer la durée de la temporisation est donc :

Registres associés au Timer2


TMR2 : c'est le registre de comptage. C'est donc dans ce registre que nous allons rentrer
la valeur de départ de notre compteur.
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).

4 Fonctions particulières des Timers

-Les Timers 0 et 1 peuvent être utilisés en compteur d’évènements extérieurs.


Exemples :
- Compteur de pièces dans une machine industrielle
- Affichage de la vitesse d’un véhicule
- Timer 0 :Signal à appliquer sur la broche RA4/T0CKI

4.1. Timer 0 en compteur d'évènements


- T0SE = 0 : les fronts montants attaquant le Timer0 correspondent aux fronts montants de
RA4/T0CKI
- T0SE = 1 : les fronts montants attaquant le Timer0 correspondent aux fronts descendants
deRA4/T0CKI

4.2. Timer 1 en compteur d'évènements


La broche du PIC associée au Timer 1 est la ligne RC0/T1OSO/T13CKI :
- La ligne RC1/T1OSI est aussi associée au Timer 1, mais ne joue pas de rôle dans le
comptaged'événements extérieurs.
- Compte tenu de la remarque ci-dessus, il faut déconnecter la ligne RC1 / T1OSI en
invalidantla 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
pouravoir 1s).
T1OSCEN = 1
5.Manipulations
Dans ce projet la minuterie, sur la base de registre TMR0, est utilisée comme un compteur.
L'entréede comptage est reliée à un bouton-poussoir Input de sorte que toute pression sur Input
provoqueTMR0 à compter une impulsion. Lorsque le nombre d'impulsions correspond au
nombre stocké dansle registre nommé TEST, la valeur logique 1 (5V) apparaît sur le pin3 de
PORTD. Cette tensionactive un relais électromécanique, et ce bit est appelé « RELAI » dans le
programme.
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 4qui 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 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
TMR0 = 100; // TMR0 compte de 100 à 255
INTCON = 0xA0; // Interruption par TMR0 est autorisés
cnt = 0; // Variable cnt est initialisée à 0
do
{
if (cnt == 400)
{ // Incrémenter port B après 400 interruptions
PORTB = PORTB++; // Incrémenter PORTB par 1
cnt = 0; // Initialiser la variable cnt
}
}
while(1);}
On voit que l’Interruption se produit sur chaque débordement du registre TMR0. Le nombre
d’interruption à 400, dans cet exemple, provoque l’incrémentation du PORTB comme indique
lafigure ci-dessous.

Dans le code-source 3 (fichier INTERRUP_TMR1) on utilise l’interruption produit par le


débordement de registre TMR1(TMR1H, TMR1L). Après 76 d’interruption se produit
l’évolution surle PORTB comme indique la figure ci-dessous

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;
TMR1L = 0x00; // Valeurs initiales du TMR1H and TMR1L
}
void main()
{
ANSEL = 0; // Broches E/S sont configure en numériques
ANSELH = 0;
PORTB = 0xF0; // Initialisation de PORTB
TRISB = 0; // PORTB est configuré en sortie
T1CON = 1; // Remise à 1 du TMR1
PIR1.TMR1IF = 0; // Remise à 0 du TMR1IF
TMR1H = 0x80; // Initialisation du TMR1
TMR1L = 0x00;
PIE1.TMR1IE = 1; //Activer l’interruption en cas de débordement du TMR1
cnt = 0; // Remis à 0 la variable cnt
INTCON = 0xC0; // Activer interruption (bits GIE et PEIE)
do
{ // Boucle sans fin
if (cnt == 76)
{
PORTB = ~PORTB; //Bits du PORTB sont inversés après 76 d’interruptions
cnt = 0; // Initialisation de la variable cnt
}
}
while (1);
}