Programmation des Timers avec un PIC18F4550/PIC18F2550

Je vais essayer de vous présenter le plus simplement possible la programmation d'un Timer. L'environnement de développement utilisé est celui fourni par Microchip, c'est à dire MPLAB IDE version 8.36 et le compilateur C18 associé.

Utilisation du Timer 0

En mode Timer, le calcul du temps est relativement simple.

Calcul de la fréquence de travail

Dans mon exemple, j'utilise un quartz externe à 20 MHz, mais vu la configuration des bits internes, me permet d'avoir une fréquence interne à 48 MHz.
Chaque instruction prenant 4 cycles d'horloges, il faut donc diviser cette fréquence par 4 pour obtenir la fréquence de travail, fréquence que je nommerai Ft par la suite.

Utilisation du PRESCALER

L'utilisation du PRESCALER permet de diviser encore cette fréquence de travail. En utilisant un préscaler à 256, l'incrément des registres du Timer n'aura lieu que tous les 1/Ft * PRESCALER. L'inverse de la fréquence de travail me donne la période, que je multiplie ensuite par la valeur de préscaler. Dans mon cas, cet incrément des valeurs de registre a lieu toutes les 21.33 microsecondes.

Utilisation des registres du timer

En utilisant le mode 16 bits de ce Timer, 2 registres permettent d'affiner les valeurs. Ce sont les registres TRM0L (L pour Low) et TMR0H (H pour High). Pour avoir une période maximum, il faut que la valeur de ces 2 registres soit minimum.
En effet, c'est le dépassement de capacité de ce compteur qui déclenche l'interruption. Pour réduire la période d'interruption, il faut donc initialiser ce compteur avec une valeur différente de 0.
Si les valeurs des registres TMR0H et TMR0L sont initialisés à 0, un interruption sera déclenchée toutes les 21.33 microsecondes * 65535 = 1,398 secondes.

Le code

Initialisation

INTCONbits.GIE = 0; //On bloque toutes les interruptions
INTCONbits.TMR0IE = 1; //On valide le timer 0
T0CON = 0b10000111; //paramètrage du timer 0, 16 bits et diviseur par 256
TMR0H = 0; //On initialise le "compteur"
TMR0L = 0;
//Authorisation des interruptions
INTCONbits.GIE = 1;

Traitement de l'interruption
void YourHighPriorityISRCode()
{
   if( INTCONbits.TMR0IF == 1) //On teste si c'est une interruption du timer 0
   {
      LATBbits.LATB7 = ! LATBbits.LATB7;//On fait clignoter la célèbre led :-)
      INTCONbits.TMR0IF = 0;//On reset l'interruption du timer
   }
}

Ajustements

La fréquence étant fixe, il faut jouer sur la valeur du PRESCALER, ainsi que sur les valeurs du compteurs afin d'obtenir une interruption au moment désiré.