PROGRAMMATION DES TIMERS
1. Objectifs
Comprendre les modes de fonctionnement des Timers.
Mettre en œuvre les interruptions des Timers en language C.
2. Rappel
Les timers sont enfait des compteurs formés généralement d’un prédiviseur suivi d’un registre compteur de 8 ou 16 bits. L’entrée d’horloge peut être interne (mode timer) ou externe (mode compteur d’événements).
Lorsque le registre compteur atteint sa valeur maximale et repasse à 0, un bit indicateur (flag) sera positionnée et une interruption pourra être générée, informant ainsi la CPU du débordement du timer. Il faut bien noter que le bit indicateur de débordement devra être remis à 0 après chaque débordement.
2.1. Timer 0
Le timer 0 est un compteur 8 bits pré positionnable par le registre « TMR0 » accessible en banque 0 ; la valeur de ce registre sera incrémentée et il sera possible de la lire à tout moment.
Le timer 0 est configuré par le registre « OPTION_REG » accessible en banque 1 et 3.
Le timer 0 peut avoir comme source d’horloge, suivant le bit « TOCS » du registre « OPTION_REG » : - soit l’horloge interne du microcontrôleur,
c’est à dire l’horloge du quartz à fréquence divisée par 4 (TOCS=0) ;
- soit une horloge externe, appliquée sur la borne TOCKI, borne multiplexée avec RA4 (TOCS=1). Dans ce cas, le comptage peut se faire sur front montant (« TOSE » de « OPTION_REG » au NL0) ou sur front descendant (TOSE=1).
Suivant le bit « PSA » de « OPTION_REG », cette horloge peut être divisée (PSA=0) ou non.
Le rapport de division est fixé de 2 à 256 suivant les bits « PS2, PS1 et PS0 » du même registre.
Noter que le pré diviseur est une ressource commune avec le « Watchdog ». Il ne pourra être utilisé que pour l’une des fonctions suivant « PSA ».
Lorsque le registre TMR0 passe de FFh à 00h, le bit « TMR0IF » (TiMeR0 Interrupt Flag) du registre « IT1CON » passe à 1.
TP4
utilisation) ;
- soit en autorisant une interruption du programme (mode interruption).
2.2 Timer 1
TMR1 est un Timer/Compteur 16 bits accessible en lecture/écriture par l'intermédiaire des registres 8 bits TMR1H (bank0) et TMR1L (bank0) qui constituent sa partie haute et sa partie basse.
On le configure à l'aide du registre T1CON (bank0)
TMR1 peut fonctionner dans 3 modes différents : - Timer Synchrone (horloge
interne)
- Compteur Synchrone (horloge externe)
- Compteur Asynchrone (horloge externe)
Le bit de contrôle TMR1CS
détermine le
fonctionnement en Timer ou
en Compteur et le bit T1SYNC détermine le mode de fonctionnement en synchrone ou en asynchrone.
TMR1 peut être arrêté/démarré à l'aide du bit TMR1ON.
TMR1 peut être RAZ à l'aide du module de capture/comparaison CCP.
TMR1 peut être précédé d'un pré diviseur (Prescaler) qui peut diviser la fréquence par 1, 2, 4 ou 8 selon la valeur des bits T1CKPS1 et T1CKPS0.
A son débordement (FFFFh ->0000h) le drapeau PIR1.TMR1IF (bank0) est positionné ce qui peut déclencher l'interruption périphérique TMR1I si elle est validée par son bit de validation PIE1.TMR1IE (bank1).
Le mode Timer
Dans ce mode, TMR1 est incrémenté par l’horloge système Fosc/4 éventuellement pré divisée. Le bit de synchronisation n'a pas d'effet car l'horloge Fosc/4 est toujours synchronisée sur l'horloge système.
Le mode Compteur
Dans ce mode, TMR1 est incrémenté à chaque front montant de l'horloge externe T1CKI (RC0) ou l'horloge dédiée générée par l’oscillateur T1OSC à condition de positionner le bit T1OSCEN à 1 et de brancher un quartz entre les broche RC0 et RC1.
En mode compteur, RC0 et RC1 sont automatiquement configurées en entrée, on n’a pas besoin de configurer les bits TRISC,0 et TRISC,1.
En fonctionnement Synchrone, l'horloge externe (éventuellement pré divisée) n'incrémente pas directement le timer mais elle est synchronisée sur l'horloge système ce qui peut entrainer un delai de l'ordre de 1 cycle machine.
En fonctionnement Asynchrone, l'horloge externe (éventuellement pré divisée) incrémente le timer indépendamment de l'horloge système.
En mode Compteur Asynchrone, on ne peut pas utiliser les modules CCP1 et CCP2 pour faire des captures ou des comparaisons sur TMR1.
Le registre de contrôle de T1CON
En résumé : Le temps qui sépare 2 levés de drapeau TMR1IF est :
Si on ajoute un compteur N dans le programme on obtient un temps = N x TF1
2.3 Le Timer TMR2
TMR2 est un timer 8 bits accessible en lecture écriture constitué de :
un registre de contrôle T2CON (bank0)
un pré diviseur (1,4,16)
un registre de période PR2 (bank1) accessible en lecture/écriture
un comparateur,
un post diviseur (1 à 16).
TMR2 est incrémenté par l'horloge interne Fosc/4. Il commence à 0 et quant il atteint la valeur du registre PR2, le comparateur génère un signal qui :
- Remet TMR2 à 0.
- incrémente le postscaler qui fonctionne comme un diviseur de fréquence.
Comme le comptage commence à 0, si PR2=N, alors le comparateur annonce une égalité tous les N+1 coups d’horloge.
Au débordement du postscaler, le drapeau PIR1.TMR2IF est positionné, l'interruption correspondante est déclenchée si elle est validée.
TMR2 est remis à zéro à chaque RESET.
Le prescaler et le postscaler sont initialisés à chaque écriture dans TMR2 ou dans T2CON et au RESET du processeur.
Le fonctionnement de TMR2 est configuré à l'aide du registre de contrôle T2CON : En résumé, Si on note :
DIV1 : rapport du pré diviseur DIV2 : Rapport du post diviseur P : Valeur placée dans le registre PR2 Tsy : période de l'horloge système,
la périodicité du drapeau TMR2IF est donnée par : TF2 = DIV1 x (P+1) x DIV2 x Tsy .
Le mode scrutation
Nous savons maintenant que tout débordement du timer, entraine le positionnement du bit indicateur de débordement (TOIF dans le cas du timer0 par exemple). Vous pouvez donc utiliser cet indicateur (flag) pour déterminer si le timer a débordé ou non.
Exp : while(TOIF == 0) ; //Attendre le débordement du timer0 pour sortir.
TOIF = 0 ; //N’oubliez pas de remettre ce bit à 0.
Le mode interruption
C’est le mode principal d’utilisation des timers. En effet, pour qu’une interruption se déclenche à chaque passage du bit indicateur de débordement à 1, il faut positionner à l’avance les bits de validation de l’interruption.
Pour que l’interruption timer 0 se déclenche lorsque T0IF passe à 1, il faut positionner les bits T0IE et GIE.
Pour que l’interruption timer 1 se déclenche lorsque TMR1IF passe à 1, il faut positionner les bits TMR1IE, PEIE et GIE.
Pour que l’interruption timer 2 se déclenche lorsque TMR2IF passe à 1, il faut positionner les bits TMR2IE, PEIE et GIE.
Dés que le timer déborde, la CPU se branche automatiquement à une routine précédée par le mot reservé #int_timer0 par exemple.
Exemple de programmation d’une interruption :
On veut faire clignoter la LED RC2 à une fréquence approximativement à 2 Hz. On admet que la fréquence dequartz est Fosc=8MHz.
---
La fréquence de clignotement Fc=2Hz Tc = 500ms.
Le timer provoque à chaque débordement, une interruption. La période de débordement Td doit etre la moitié de Tc donc Td = 250ms.
La période maximale de débordement du timer 0 :
Td0max = 4*Tosc*Predivmax*28=4*0.125µs*256*256=32.768ms ; or nous voulons une période de 250ms environ. Cherchons alors la période maximale de débordement du timer 1 :
Td1max = 4*Tosc*Predivmax*216=4*0.125µs*8*65536=262.0144ms ; cette valeur pourra etre acceptable.
On doit configurer le timer 1, en mode timer (horloge interne) avec une valeur de pré division égale à 8 ; d’où T1CON = 00110001=31h.
---
// Mise en œuvre du timer 1
#include <16F877.h>
#include "REG16F.h"
#use delay(clock=4000000)
#fuses HS,NOPRPTECT, NOWDT, NOLVP,PUT Void init()
{ TRISC = 0x0; //PORTC en sortie
T1CON = 0x31; //configuration du timer 1 TMR1IE = 1 ; //validation de l’IT timer1
PEIE =1 ; //validation de l’IT périphériques GIE = 1 ; //validation globale des IT }
#int_timer1
Void interrupt() // routine d’IT
{ RC2 = !RC2 ; // inversion de l’état de la LED } Void main()
{init(); // appel de la procédure init while(1); // boucle infinite }
Travail à faire : Préparation
:On veut configurer l’un des timers pourqu’il déborde toutes les 20 ms. La fréquence du microcontroleur est Fosc=8Mhz.
1. Quel est le mode de fonctionnement à choisir (mode timer ou mode compteur) ?
2. Donner pour chacun des timers, les valeurs à charger dans les registres qui lui sont associés.
a. Pour le Timer0 : Prediv= ?; TMR0= ?; OPTION_REG= ? b. Pour le Timer1 : Prediv= ?; TMR1L= ?; TMR1H= ?; T1CON= ? c. Pour le Timer2 : Prediv= ?; PR2= ?; Postdiv= ?; T2CON= ? 3. Quel est le timer qui convient le mieux ?
Manipulation :
Le mode Timer
1. Tester le programme de clignotement d’une LED.
2. Modifier le programme pourque la LED clignote à 2 Hz exactement.
3. Réecrire le programme précédent en mode scrutation.
4. Réecrire le programme de clignotement d’une LED, en utilisant le timer 2 au lieu du timer 1.
Le mode compteur (faites la simulation des programmes avec ISIS)
1. Ecrire un programme qui incrémente le contenu du registre TMR0 à chaque appui sur le bouton RA4. Afficher le compte sur les LEDs connectées au PORTC.
2. Modifier le programme pourque le registre TMR0 s’incrémente après 4 appuis sur le bouton RA4.