Dernière mise à jour le 10/02/18

Présentation


Vous allez me dire que c’est la même chose que le timer1 ?? Oui mais non je vous assure que celui-ci est encore plus performant. En effet, celui-ci permet de combiner le Timer3 pour obtenir 32 bits plutôt que 16 bits, voilà cette différence alors que je tiens à le vous rappeler, le Timer1 comme le Timer2 ne fait que 16 bits …
 




 
L’exemple qui va suivre utilise le Timer2 sur 16 bits, et va permet de faire clignoter 2 leds toutes les secondes. La led verte représente le programme principal, et la led rouge le programme d’interruption.

Schéma PIC32 Interruptions Timer2


Programme PIC32 Interruptions Timer2


Programme disponible aussi en MikroC

program PIC32_Interruptions_Timer2;
 
procedure init;
begin
AD1PCFG := $FFFF; // Utilisation des entrées en numériques
TRISB := $0000; // Les broches du PORTB sont configurées en sorties
LATB := $0000; // Initialise toutes les sorties du PORTB à l’état logique BAS
PORTB :=$0000; // On fixes les sorties à l’état zéro
 
EnableInterrupts(); // Activations des interruptions IVT
 
ON__T2CON_bit:=1; // On active le timer 2
 
SIDL_T2CON_bit:=0;
 
TCKPS0_T2CON_bit:=1; // |
TCKPS1_T2CON_bit:=1; // | prescaler sur 256
TCKPS2_bit:=1; // |
 
T32_bit:=0; // Timer2 config sur 16 bits
 
TCS_bit:=0; // Horloge interne (Quartz OSC1 et OSC2) 8MHZ
 
T2IE_bit:=1; // On active les interrutpions du Timer2
T2IF_bit:=0; // Drapeau d’interrutpion baissé
 
T2IP0_bit:=1; // |
T2IP1_bit:=1; // | pritorité 7 de l’interruption du timer 2
T2IP2_bit:=1; // |
 
TMR2:=$0000; // Le réglage à zéro le Timer2 c’est mieux pour commencer…
 
end;
 
procedure Timer2();
iv IVT_TIMER_2; // Interrutpion timer3 priorité 7
ilevel 7;
begin
if T2IF_bit=1 then //T2IF représente les 256 coups d’horloge du timer2
begin
delay_ms(1000);
LATB.4:=1; // Led rouge allumée interruption en cours…
LATB.1:=0; // Led verte éteinte programme principale arrêté
delay_ms(1000);
LATB.4:=0; // Led rouge éteinte fin de l’interruption
T2IF_bit:=0; // On sort de l’interruption
end;
end;
 
begin
init;
while true do
begin
LATB.1:=1; // Led verte allumée programme principale en cours…
end;
end.

Ce programme est fonctionnel, mais vous avez remarquez que j’ai utilisé des tempos de 1 seconde pour ralentir l’interruption qui occasionne par la même occasion le ralentissement du programme principal (led verte). C’est façon de faire n’est pas très élégante mais cela vous donne un premier aperçu de l’utilisation des interruptions du Timer2.
 
Nous allons voir maintenant comment utiliser le Timer2 et le Timer3 afin de pouvoir compter sur 32 bits. L’exemple qui va suivre permet de fair clignoter les 2 leds à la secondes

Programme PIC32 Interruptions Timer2 Timer3


Programme disponible aussi en MikroC

program PIC32_Interruptions_Timer2_Timer3;
 
procedure init;
begin
AD1PCFG:=$FFFF; // Utilisation des entrées en numériques
TRISB:=$0000; // Les broches du PORTB sont configurées en sorties
LATB:=$0000; // Initialise toutes les sorties du PORTB à l’état logique BAS
PORTB:=$0000; // On fixe les sorties à l’état zéro
 
EnableInterrupts(); // Activations des interruptions IVT
 
ON__T2CON_bit:=1; // On active le Timer2
 
TCKPS0_T3CON_bit:=0; // |
TCKPS1_T3CON_bit:=0; // | Timer3 réglé prescaler à 1:1
TCKPS2_T3CON_bit:=0; // |
 
T32_bit:=1; // Mode 32 bits (Timer2 + Timer3)
 
T3IP0_bit:= 1; // |
T3IP1_bit:= 1; // | Priorité 7
T3IP2_bit:= 1; // |
 
T3IF_bit:= 0; // On met le drapeau à zéro (Pas d’interrutpion)
T3IE_bit:= 1; // On active les interrutpion du Timer3
 
TMR2:= 0; // On commence à compter à partir de zéro
TMR3:= 0; // On commence à compter à partir de zéro
PR2:= 47300;
PR3:= 1220;
 
LATB.4:=1;
LATB.1:=0;
end;
 
procedure Timer2();
iv IVT_TIMER_3; // Interrutpion timer3 priorité 7
ilevel 7;
begin
if T3IF_bit=1 then //T3IF est à 1 lorsque Timer2/3 égale PR2/PR3
begin
LATB.4:= LATB.4 xor 1; // Led rouge
LATB.1:= LATB.1 xor 1; // Led verte
T3IF_bit:=0;
end;
end;
 
begin
init;
while true do
begin
// On ne fait rien
end;
end.

Dans ce nouveau programme apparait PR2 et PR3, qui sont des bits qui permettent de fixer une valeur pour que celle-ci soit comparée par rapport à la valeur du comptage des Timer2/3. Lorsque la valeur PR2 et PR3 sera égale à la valeur du Timer2/3 nous obtiendrons une interruption.

Dans ce mode de 32 bits, en associant le Timer 2/3 celui-ci compte de 0 à 4294967295. Ce qu’il faut comprendre c’est que le Timer2 compte sur 16 bits, et le Timer 3 compte aussi sur 16 bits et la somme des 2 formes un compteur de 32 bits. Le Timer2 compte de 0 à 65535 et quand il arrivera à 65535 il incrémentera le Timer3. De nouveau le Timer recompte de 0 à 65535 et arrivé à 65535 il va de nouveau incrémenter le Timer3 soit deux incrémentations obtenu au Timer3. De nouveau on recommence le cycle le Timer2 terminer de compter et le Timer3 s’ incrémente une 3ème fois etc … etc….
 
La question est : Quelles sont les valeurs à donner à PR2 et PR3 pour que les leds clignotent toutes les secondes avec un CPU qui tourne à 80 Mhz et un prescaler de 256? Et bien facile !!! PR2= 47300 et PR3 = 1220 !!!
 
Bon ok !! Je vous vois venir ! comment fait-on pour calculer ?
Soit vous utilisez la solution la plus facile, et qui est de télécharger sur le site de Mikroe le « Timer Calculator » à cette adresse :
https://libstock.mikroe.com/projects/view/398/timer-calculator
 
Ou bien vous jouez de la calculette à savoir que vous allez tronquez les chiffres qui sont situé après la virgule afin de simplifier au maximum !

Calculatrice au secours!!!


Le Timer2 comme le Timer3 est cadencé à une vitesse de 80 Mhz soit toutes les 0,01micro-seconde. Imaginer vous que toutes les Microsecondes le Timer2 incrémenter de 1 cela va très vite, et il aura donc mis 820 microsecondes pour arriver à 65535. Dans ce cas le Timer2 une fois terminé de compter va incrémenter le Timer3, et le cycle recommence. On obtient quelque chose du genre:
 
– 1er tour de comptage pour le Timer2 = 65535 + 1 (incrément) pour le Timer3 total = 65536
– 2ème tours de comptage pour le Timer2 = 2×65535 + 2×1(incrément) pour le Timer3 total = 131072
– 3ème tour de comptage pour le Timer2 = 3×65535 + 3×1(incrément) pour le Timer3 total = 196608
– etc…

Calculs

D’une manière général on peut démontrer par cette formule que :

PR3 = x*F/(Prescaler*65536)
PR2 = (x*F)[1/Prescaler – PR3*65535]

x : le temps que l’on souhaite obtenir en seconde ;
F : la fréquence en Hz (ici 80 000 000 hz)
Prescaler : ici dans notre exemple il est de 1 : 1 pour notre programmation
 
En valeur numériques cela nous donne :

PR3 = (1*80 000 000)/[(1/1)*65536] = 1220,703125 soit 1220 par arrondi.
PR3 = 1220

PR1 = (1*80 000 000)[1/(1/1)-( 1220*65535)] = 47300
PR2 = 47300

Lorsque le PR3 aura atteint 1220 coup d’horloge via le Timer3, il faudra ensuite attendre que PR2 soit arrivé à 47300 coup d’horloge via le Timer2 ce qui entrainera dans la foulé la mise à 1 du bit T3IF et donc une 1 interruption.

Historiques


– 10/02/18
Programmation disponible aussi en MikroC.
– 03/02/18
Première mise à disposition.