14
Microcontrôleurs Iset de Nabeul Mr Nizar TOUJENI 81 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)

14- Lecon 9 - Timers - Technologue pro, cours ... · Le 16F877 en compte 3 : ... TMR0 : c'est le registre de comptage. C'est donc dans ce registre que nous allons rentrer la valeur

  • Upload
    vudan

  • View
    221

  • Download
    0

Embed Size (px)

Citation preview

Page 1: 14- Lecon 9 - Timers - Technologue pro, cours ... · Le 16F877 en compte 3 : ... TMR0 : c'est le registre de comptage. C'est donc dans ce registre que nous allons rentrer la valeur

Microcontrôleurs Iset de Nabeul

Mr Nizar TOUJENI 81

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)

Page 2: 14- Lecon 9 - Timers - Technologue pro, cours ... · Le 16F877 en compte 3 : ... TMR0 : c'est le registre de comptage. C'est donc dans ce registre que nous allons rentrer la valeur

Microcontrôleurs Iset de Nabeul

Mr Nizar TOUJENI 82

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

Page 3: 14- Lecon 9 - Timers - Technologue pro, cours ... · Le 16F877 en compte 3 : ... TMR0 : c'est le registre de comptage. C'est donc dans ce registre que nous allons rentrer la valeur

Microcontrôleurs Iset de Nabeul

Mr Nizar TOUJENI 83

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 au

compteur 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.

Page 4: 14- Lecon 9 - Timers - Technologue pro, cours ... · Le 16F877 en compte 3 : ... TMR0 : c'est le registre de comptage. C'est donc dans ce registre que nous allons rentrer la valeur

Microcontrôleurs Iset de Nabeul

Mr Nizar TOUJENI 84

Calcul d'un temps de 10

ms

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).

Dans ce chapitre, nous ne nous intéresserons qu'au bit 2 appelé T0IF et qui correspond au flag

Page 5: 14- Lecon 9 - Timers - Technologue pro, cours ... · Le 16F877 en compte 3 : ... TMR0 : c'est le registre de comptage. C'est donc dans ce registre que nous allons rentrer la valeur

Microcontrôleurs Iset de Nabeul

Mr Nizar TOUJENI 85

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

}

Page 6: 14- Lecon 9 - Timers - Technologue pro, cours ... · Le 16F877 en compte 3 : ... TMR0 : c'est le registre de comptage. C'est donc dans ce registre que nous allons rentrer la valeur

Microcontrôleurs Iset de Nabeul

Mr Nizar TOUJENI 86

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

Durée de comptage maximale

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 :

Page 7: 14- Lecon 9 - Timers - Technologue pro, cours ... · Le 16F877 en compte 3 : ... TMR0 : c'est le registre de comptage. C'est donc dans ce registre que nous allons rentrer la valeur

Microcontrôleurs Iset de Nabeul

Mr Nizar TOUJENI 87

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.

Page 8: 14- Lecon 9 - Timers - Technologue pro, cours ... · Le 16F877 en compte 3 : ... TMR0 : c'est le registre de comptage. C'est donc dans ce registre que nous allons rentrer la valeur

Microcontrôleurs Iset de Nabeul

Mr Nizar TOUJENI 88

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).

Page 9: 14- Lecon 9 - Timers - Technologue pro, cours ... · Le 16F877 en compte 3 : ... TMR0 : c'est le registre de comptage. C'est donc dans ce registre que nous allons rentrer la valeur

Microcontrôleurs Iset de Nabeul

Mr Nizar TOUJENI 89

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 de

RA4/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 :

Page 10: 14- Lecon 9 - Timers - Technologue pro, cours ... · Le 16F877 en compte 3 : ... TMR0 : c'est le registre de comptage. C'est donc dans ce registre que nous allons rentrer la valeur

Microcontrôleurs Iset de Nabeul

Mr Nizar TOUJENI 90

� 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.

Page 11: 14- Lecon 9 - Timers - Technologue pro, cours ... · Le 16F877 en compte 3 : ... TMR0 : c'est le registre de comptage. C'est donc dans ce registre que nous allons rentrer la valeur

Microcontrôleurs Iset de Nabeul

Mr Nizar TOUJENI 91

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

Page 12: 14- Lecon 9 - Timers - Technologue pro, cours ... · Le 16F877 en compte 3 : ... TMR0 : c'est le registre de comptage. C'est donc dans ce registre que nous allons rentrer la valeur

Microcontrôleurs Iset de Nabeul

Mr Nizar TOUJENI 92

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

Page 13: 14- Lecon 9 - Timers - Technologue pro, cours ... · Le 16F877 en compte 3 : ... TMR0 : c'est le registre de comptage. C'est donc dans ce registre que nous allons rentrer la valeur

Microcontrôleurs Iset de Nabeul

Mr Nizar TOUJENI 93

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 la

figure 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 sur

le 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;

Page 14: 14- Lecon 9 - Timers - Technologue pro, cours ... · Le 16F877 en compte 3 : ... TMR0 : c'est le registre de comptage. C'est donc dans ce registre que nous allons rentrer la valeur

Microcontrôleurs Iset de Nabeul

Mr Nizar TOUJENI 94

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);

}