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

Présentation


Le MINI-32 possédant le PIC32MX534F064H dispose sur ces broches de 5 captures d’entrées (Input capture). Ces broches sont :
 
PIN 42 (Broche RD8 du PIC) = IC1 correspond à l’entrée de la capture 1
PIN 43 (Broche RD9 du PIC) = IC2 correspond à l’entrée de la capture 2
PIN 44 (Broche RD10 du PIC) = IC3 correspond à l’entrée de la capture 3
PIN 45 (Broche RD11 du PIC) = IC4 correspond à l’entrée de la capture 4
PIN 52 (Broche RD4 du PIC) = IC5 correspond à l’entrée de la capture 5
 
La particularité de ces broches, c’est qu’elles peuvent au total réaliser 5 captures différentes!! Reste à savoir ce qu’est une capture, et quelles sont les plus prioritaires par rapport aux autres situés sur ces 5 entrées.

Configuration des broches


Essayons de comprendre comment fonctionne ces captures en entrée de notre PIC32

Les cadres rouge représentes les entrées de capture.

Registre ICxCON


Le registre ICxCON (avec « x » à remplacer par 1 ou 2 ou 3 ou 4 ou 5 qui correspond 5 captures toutes indépendantes) permet d’attribuer des bits correspondant dans chaque registres que nous désirons utiliser.
 
Si nous décidons uniquement d’activer le module via le bit « ON » , il faudra donc attribuer le chiffre 1 dans la case ou est situé ON ce qui donnera d’après le tableau sur 32 bits :
00000000 00000000 10000000 00000000
(de gauche à droite 1er ligne du tableau de 8bits, 2ème ligne du tableau de 8 bits, 3ème ligne de tableau de 8 bits, etc…)

Si pour une autre raison vous décidez de rajouter le bits ICI ( sur 2 bits : bit 0 et bits 1) à 1 cela nous donne :
00000000 00000000 10000000 01100000
 
Vous voyez cela en fait des « 0 » et des « 1 » à écrire !! Vous ne trouvez pas ? La chance que vous avez puisque c’est uniquement sur 32 bits quand serait-t-il de 64 bits ou voir même 128 ??!! Attention aux tendinites !!!

Routine MikroPascal nous sauves !!!


Ouf !!! Oui !! Comme dis précédemment, heureusement que les routines sont là pour nous faciliter la tâche. Plutôt que d’attribuer des « 0 » ou des « 1 » logique, il suffit de récupérer ces bits situés dans la routine MikroPascal. En reprenant les exemples précédents cela nous donnerais :
 
L’activation du module “ON” devient avec la routine de MikroPascal:

ON__IC1CON_bit:=1;

Et pour activer “ICI” sur les 2 bits cela devient:

ON__IC1CON_bit:=1;
ICI0_bit:=1; // bit « 0 » à l’état logique 1
ICI1_bit:=1; // bit « 1 » à l’état logique 1

On s’aperçoit que c’est beaucoup plus parlant, plus simple et cela nous évite de faire des erreurs qu’en pensez-vous ?

Les autres bits ?

ON/SIDL/FEDGE/C32/ICTMR/ICI/ICOV/ICBNE/ICM ???? Mais c’est quoi tout ça? Et à quoi cela peut bien servir ? Si vous voulez des détails vous pouvez voir sur le DataSheets du constructeur.
 
Pour faire simple :
 
ON : Permet d’activer le module de capture 1/2/3/4/5 capture en même temps à vous de choisir
SIDL : soit en mode sommeil soit en mode continu (tout le temps actif)
FEDGE : la capture sur l’entrée correspondante se fait soit sur un front montant soit sur un front descendant
C32 : Vous utiliser soit un compteur qui compte sur 32 bits (de 0 à 429 496 72 95) soit sur 16 bit (de 0 à 65535)
ICTMR : Timer 2 / Timer 3 pour compter soit sur 16 bits soit sur 32 bits.
ICI : Un déclenchement d’interruption est réalisé soit sur 1 évènement soit sur 2 évènements soit sur 3 ou voir même sur 4 événements.
 
Remarques : Lorsque vous réglé le bit ICI , ce bit est à mis à l’état 1 logique sur le premier événements de capture et restera à l’état logique 1 tant que tous les événements de captures non pas été lus à partir du FIFO ou buffer (ICxBUF). Il en résulte qu’il faut lire ces évènements pour vider le Buffer.
 
– 1 évènement, il faut lire le buffer au moins 1 fois ou plus pour le vider
– 2 évènements, il faut lire le buffer au moins 2 fois ou plus pour le vider
– 3 évènements, il faut lire le buffer au moins 3 fois ou plus pour le vider
– 4 évènements, il faut lire le buffer au moins 4 fois ou plus pour le vider
 
Attention !! Ceci est primordial afin de pouvoir vider complétement et correctement le buffer !!
 
ICOV/ICBNE : sont des bits en lectures seules on ne peut uniquement lire ces bits mais on ne peut pas écrire dedans seul le PIC pilote ces bits !!
Le bit ICBNE est utilisé afin de vérifier si le buffer est vidé totalement. Le buffer se vide via le bit ICxBUF (x à remplacerpar 1 ou 2 ou 3 ou bien 4) voir plus bas…
 
ICM : l’entrée permet de compter le nombre de front qui arrive sur ces broches ICx (x à remplacer soit par 1 ou 2 ou 3 ou 4 ou 5). Soit un seul front soit 4 soit 16 ou bien un front montant et un front descendant il suffit de tester pour en avoir le cœur net !!

ICxBUF

Ce bit permet de lire le Buffer et par la même occasion une fois lu, le buffer est vidé en fonction de nombre d’évènements autorisés (1 événement = 1 lecture /2 événements = 2 lecture / etc…)

Schéma


Programme PIC32 Input Capture – 1 évenement et 4 fronts montant


Programme disponible aussi en MikroC

program PIC32_Input_Capture;

var
ViderBufferLecture1:word;
 
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
 
TRISD8_bit:=1; // La broche du PORTD.8 est configurée en entrée
LATD := 0; // Initialise toutes les sorties du PORTD à l’état logique BAS
 
EnableInterrupts(); // Activations des interruptions IVT
 
ON__IC1CON_bit:=1; // On active le module de Capture 1
//IC1CON := $83E3; // la même chose en HEX
//IC1CON := 00000000000000001000001111100011// et en BIN
 
SIDL_IC1CON_bit:=0; // Mode continu
FEDGE_bit:=1; // Capture sur front montant
C32_bit:=0; // mode 16 bits Timer 2 uniquement
 
ICTMR_bit:=1; // Timer 2
 
ICI0_bit:=0; // | Déclenchement de l’interruption
ICI1_bit:=0; // | sur le 1er événement
 
ICM0_bit:=0; // |
ICM1_bit:=0; // | ICM réglé sur 4 fronts montant
ICM2_bit:=1; // |
 
IC1IE_bit:=1; // On active les interruptions sur les captures
 
IC1IP0_bit:=1; // |
IC1IP1_bit:=1; // | Capture 1 sur le niveau 7
IC1IP2_bit:=1; // |
end;
 
procedure Capture_1();
iv IVT_INPUT_CAPTURE_1; // entrée RD8 pour la capture 1
ilevel 7;
begin
 
begin
LATB.1:=1; // Une interruption survient
delay_ms(1000); // On attend un peu avant de lire le buffer
// Lecture du Buffer pour effacer l’interruption
ViderBufferLecture1:=IC1BUF; // 1ère lecture pour effacer la 1er évenement de capture
delay_ms(1000); // On attend un peu avant la fin de la lecture
LATB.1:=0; // La capture et la lectrue est fini
end;
 
begin
if ICBNE_bit=1 then //ICBNE reste à 1 temps que le buffer n’a pas été lu
begin
LATB.4:=1;
end;
end;
 
begin
if ICBNE_bit=0 then // buffer (FIFO) vidé
begin
LATB.4:=0;
end;
end;
IFS0:=0; // La remise à zéro du drapeau permet de sortir de l’interruption
end;
 
begin
init;
while true do
begin
// On ne fait rien dans le programme principal
end;
end.

Dans cet exemple, j’ai programmé le PIC32 afin qu’il puisse réaliser une capture sur chaque 4ème front montant en paramétrant correctement le bit ICM (bit 0/1/2). Le 4ème capture sur front montant déclenchera une interruption qui celle-ci allumera la led verte.
Petite précision tout de même au niveau du déclenchement de l’interrutpion. Il faut avant tout sélectionner le nombre d’événements qui correspond au bit ICI, celui-ci est mis à l’état logique “0” pour le bit 1 ainsi que le bit 0 de qui donne :

ICI0_bit:=0; // | Déclenchement de l’interruption
ICI1_bit:=0; // | sur le 1er événement

Ces bits permettent de contrôler les événements, et il permet de “retarder” les interruptions en fonction du nombre d’événement choisi en agissant sur ces 2 bits. Dans notre cas, puisque ces 2 bits sont à l’état « 0 » il s’agit d’un événement et celui-ci va se produire au bout de la 4ème capture (ou 4ème front montant) puisque je le rappel nous avons régler le bit ICM sur 4 front montant.
 
Lorsque chaque front montant vont se produire sur la broche RD8 du PIC32, le 4ème front montant déclenchera l’interruption « IVT_INPUT_CAPTURE_1 » ainsi la led verte s’allumera et 1 seconde après nous viderons le buffer qu’une seule fois puisque il s’agit d’un seul événement. Attention !! Ne pas confondre l’événement et la capture.
 
Mais c’est quoi un événement ? Un événement correspond à un cycle, et on règle le nombre d’événement via le bit ICI. Reprenons l’exemple précédent. Puisque nous avons sélectionné une capture sur chaque 4ème front montant et que nous avons sélectionné 1 seul événement, il en résulte que tout les 4èmes fronts montant une interruption va se produire.
 
Je vais prendre un autre exemple afin que vous puissiez bien assimilé. Gardons toujours 4 front montant, mais cette fois-ci réglons les bits ICI afin d’obtenir 3 événements ! ! Cela nous donnerais ceci en termes de programmation :

ICI0_bit:=0; // | Déclenchement de l’interruption
ICI1_bit:=1; // | sur le 3ème évenement

Il en résulte qu’il faudra 12 front montant pour déclencher l’interruption
– 1er événement = 4 front montant;
– 2ème événement = 8 front montant;
– 3ème événement = 12 front montant;

4 événements et 4 fronts montants encore un exemple!


Continuons sur un autre exemple tout en gardant le même schéma électronique. Ici le programme qui va suivre est réalisé sur 4 événements et 4 fronts montants. Je vous laisse lire le programme qui va suivre. Notez que le buffer est vidé 4 fois!!

ICI0_bit:=1; // | Déclenchement de l’interruption
ICI1_bit:=1; // | sur le ‘ème événement

Ces bits permettent de contrôler les événements, et il permet de “retarder” les interruptions en fonction du nombre d’événement choisi en agissant sur ces 2 bits. Dans notre cas, puisque ces 2 bits sont à l’état « 0 » il s’agit d’un événement et celui-ci va se produire au bout de la 4ème capture (ou 4ème front montant) puisque je le rappel nous avons régler le bit ICM sur 4 front montant.
 
Lorsque chaque front montant vont se produire sur la broche RD8 du PIC32, le 4ème front montant déclenchera l’interruption « IVT_INPUT_CAPTURE_1 » ainsi la led verte s’allumera et 1 seconde après nous viderons le buffer qu’une seule fois puisque il s’agit d’un seul événement. Attention !! Ne pas confondre l’événement et la capture.
 
Mais c’est quoi un événement ? Un événement correspond à un cycle, et on règle le nombre d’événement via le bit ICI. Reprenons l’exemple précédent. Puisque nous avons sélectionné une capture sur chaque 4ème front montant et que nous avons sélectionné 1 seul événement, il en résulte que tout les 4èmes fronts montant une interruption va se produire.
 
Je vais prendre un autre exemple afin que vous puissiez bien assimilé. Gardons toujours 4 front montant, mais cette fois-ci réglons les bits ICI afin d’obtenir 3 événements ! ! Cela nous donnerais ceci en termes de programmation :

Programme disponible aussi en MikroC

program PIC32_Input_Capture;

var
ViderBufferLecture1,ViderBufferLecture2,ViderBufferLecture3,ViderBufferLecture4:word;
 
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
 
TRISD8_bit:=1; // La broche du PORTD.8 est configurée en entrée
LATD := 0; // Initialise toutes les sorties du PORTD à l’état logique BAS
 
EnableInterrupts(); // Activations des interruptions IVT
 
ON__IC1CON_bit:=1; // On active le module de Capture 1
//IC1CON := $83E3; // la même chose en HEX
//IC1CON := 00000000000000001000001111100011// et en BIN
 
SIDL_IC1CON_bit:=0; // Mode continu
FEDGE_bit:=1; // Capture sur front montant
C32_bit:=0; // mode 16 bits Timer 2 uniquement
 
ICTMR_bit:=1; // Timer 2
 
ICI0_bit:=1; // | Déclenchement de l’interruption
ICI1_bit:=1; // | sur le 4ème événements
 
ICM0_bit:=0; // |
ICM1_bit:=0; // | ICM réglé sur 4 fronts montant
ICM2_bit:=1; // |
 
IC1IE_bit:=1; // On active les interruptions sur les captures
 
IC1IP0_bit:=1; // |
IC1IP1_bit:=1; // | Capture 1 sur le niveau 7
IC1IP2_bit:=1; // |
end;
 
procedure Capture_1();
iv IVT_INPUT_CAPTURE_1; // entrée RD8 pour la capture 1
ilevel 7;
begin
 
begin
LATB.1:=1; // Une interruption survient
delay_ms(1000); // On attend un peu avant de lire le buffer
// Lecture du Buffer pour effacer l’interruption
ViderBufferLecture1:=IC1BUF; // 1ère lecture pour effacer la 1er évenement de capture
ViderBufferLecture2:=IC1BUF; // 2ème lecture pour effacer la 2ème évenements de capture
ViderBufferLecture3:=IC1BUF; // 3ème lecture pour effacer la 3ème évenements de capture
ViderBufferLecture4:=IC1BUF; // 4ème lecture pour effacer la 4ème évenement de capture
delay_ms(1000); // On attend un peu avant la fin de la lecture
LATB.1:=0; // La capture et la lectrue est fini
end;
 
begin
if ICBNE_bit=1 then //ICBNE reste à 1 temps que le buffer n’a pas été lu
begin
LATB.4:=1;
end;
end;
 
begin
if ICBNE_bit=0 then // buffer (FIFO) vidé
begin
LATB.4:=0;
end;
end;
IFS0:=0; // La remise à zéro du drapeau permet de sortir de l’interruption
end;
 
begin
init;
while true do
begin
// On ne fait rien dans le programme principal
end;
end.

Comment Allumée la led rouge?

êtes vous posé la question concernant la led rouge? et bien si vous voulez quelle s’allume reprenez le code ci-dessus et supprimer juste cette ligne:

ViderBufferLecture4:=IC1BUF; // 4ème lecture pour effacer la 4ème évenement de capture

Mais pourquoi elle s’allume maintenant Et bien comme dis précédemment sur 4 événements il faut vider 4 fois le buffer tout simplement 😉

Historiques


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