Dernière mise à jour le 06/09/17

Présentation

Nous allons voir dans ce présent article comment utiliser le mode capture (CCP) d’un PIC et de réaliser une mesure en centimètre près. Pour ma part j’utilise le PIC de la famille 18F plus précisément le PIC 18F45K22. Le CCP permet de détecter le front montant ou bien descendant ou voir même les 2 à la fois. Il faudra tout d’abord spécifier l’entrée qui sera “percuter” par ce front afin que le PIC puisse réaliser les calculs afin de connaitre le temps mis entre la montée et la descente de l’impulsion. Ce montage électronique va donc permettre de mesure la largeur de l’impulsion issue sur sa broche.




Afin de connaitre cette largeur d’impulsion, nous allons utiliser un ecran LCD 12×16 caractères pour afficher cette mesure. Par la suite on verra comment utiliser un tel montage électronique et de comprendre sont utilisation.

Schéma


Fonctionnement

Avant de rentrer dans les détails assez techniques il faut avant tout faire le tour au niveau du datasheet au chapitre CAPTURE/COMPARE/PWM.
Le PIC18F45K22, contient 3 modules renforcés (ECCP1/ECCP2/ECCP3) ,puis 2 autres modules standard CCP4/CCP5. Ces modules sont retrouvés sur les broches :
RC2 = CCP1
RC1/RB3 = CCP2
RC6/RB5/RE0 = CCP3
RB0/RD1 = CCP4
RA4/RE2 = CCP5

C’est en mode Capture que nous allons travailler en utilisant le périphérique CCP1 de la broche du PIC 18F45K22.

Registre CCPTMRS0

Une fois sélectionner le mode, nous allons maintenant nous intéresser à une autres option et qui permet de « capturer » un évènement lorsque celui-ci ce produit sur la broche du PIC.Il s’agit du registre CCPTMRS0 qui permet d’utiliser le mode CAPTURE/COMPARE pour le timer1.

En mode Capture il est possible d’utiliser les Timer1, Timer3 et Timer5 qui travail sur 16 bits chacun. A savoir que pour notre cas nous allons utiliser uniquement le Timer1 puisque celui-ci correspond au CCP1 = Timer1 (CCP3=Timer3, etc…).
Le registre CCPTMRS0 va permettre de sélectionner le type de front que nous voulons obtenir (front montant et front descendant). Afin d’initialiser le PIC à sa mise sous tension et que celui-ci utilise bien le Timer1, nous allons donc faire le réglage de ce bits soit:
CCPTMRS0.C1TSEL0:=0;
CCPTMRS0.C1TSEL1:=0;

Nous pouvons désormais utiliser le mode compare/capture (je suis sûr que vous l’avez remarqué, les modes compares et capturse sont activés en même temps).

Registre CCP1CON

Le registre CCP1CON quant à lui, va permettre de régler si nous voulons déclencher le Timer1 sur front montant ou sur front descendant les deux cas sont bien sûr possible aussi.

Nous allons donc régler CCP1CON sur un front montant (nous verrons plus tard comment le passer sur un front descendant). Pour ce faire il suffit de placer:
CCP1CON.CCP1M0 :=1
CCP1CON.CCP1M1:=0
CCP1CON.CCP1M2 :=1
CCP1CON.CCP1M3 :=0
Plutôt que d’appeler les bits 1 par 1, j’aurais pu faire de cette façon:
CCP1CON:=%00000101

Et voilà, j’ai activé sur front montant voyons la suite maintenant.

Lorsqu’un évènement (front montant ou descendant) intervient sur la broche RC2 (CCP1), une capture est effectuée, ce qui va déclencher une interruption.

Afin d’intervenir dans cette interruption, nous allons utiliser la routine nommée « procedure interrupt » de MikroPascal.

Pour utiliser les interruptions il va donc falloir activer les bits CCP1IF du registre PIR1, ainsi que le registre PIE1 pour activer les interruptions du CCP1IE.

Mais !! c’est quoi CCP1IF et CCP1IE ??? du registre PIR1 et PIE1 ???
C’est ce que nous allons voir tout de suite après…!!

Registre PIE1 et PIR1

Afin d’accéder aux bits CCP1IE et CCP1IF, il faut avant tout passer par le registre PIE1.

PIE1.CCP1IE :=1 ; En langage de programmation, cela veut dire que nous appelons dans le registre PIE1 le bits CCP1IE, et que nous mettons de bits à l’état 1 logique (on active le mode CCP1 en interruption) (voir datasheets).

PIR1.CCP1IF :=0 ; En langage de programmation, cela veut dire que nous appelons dans le registre PIR1 le bits CCP1IF, et que nous mettons de bits à l’état 0 logique, afin que le drapeau ne soit pas levé. Oui on parle de drapeau car à chaque fois qu’une interruption va se produire le drapeau sera levé (soit 1 logique). Une fois le drapeau levé il faut le redescendre (0 logique), ainsi on recommence le cycle à l’infinie en, espérant que le PIC ne nous lâche pas !!!

Programme du PIC



program Capture_Signal;
<spanstyle=”color: #ffff99;”>var

LCD_RS: sbit at LATB4_bit;
LCD_EN: sbit at LATB5_bit;
LCD_D4: sbit at LATB0_bit;
LCD_D5: sbit at LATB1_bit;
LCD_D6: sbit at LATB2_bit;
LCD_D7: sbit at LATB3_bit;
LCD_RS_Direction: sbit at TRISB4_bit;
LCD_EN_Direction: sbit at TRISB5_bit;
LCD_D4_Direction: sbit at TRISB0_bit;
LCD_D5_Direction: sbit at TRISB1_bit;
LCD_D6_Direction: sbit at TRISB2_bit;
LCD_D7_Direction: sbit at TRISB3_bit;
iHiDown: Word;
iLoDown: Word;
iResultDown: Word;
iResult: Word;
bState: boolean;
iValueResult: real;
AffResult: array[10] of char;
AffResult2: array[6] of char;
 

procedure init;
begin
PORTC:=%00000000;
TRISC:=%00000100;
LATC:=%01100000;
ANSELC:=$00; // on désactiive les entrée en numérique
CCPTMRS0.C1TSEL0:=0; // utilise le timer1 en mode capture et compare
CCPTMRS0.C1TSEL1:=0;
INTCON:=%11000000;
PIE1.CCP1IE:=1; // on active les interruption du CCP1
PIR1.CCP1IF:=0;// on met le drapeau en bas c'est mieux pour commencer la course
CCP1CON:=%00000101; //On active au départ le front montant
T1CON:=%01000001;
TMR1H:=$00;
TMR1L:=$00;
Lcd_Init();
Lcd_Cmd(_LCD_CURSOR_OFF);
bState:=True;
end;

procedure Interrupt;
begin
begin
if ((PIR1.CCP1IF=1) and (bState=True)) Then
begin
TMR1H:=$00;
TMR1L:=$00;
bState:=False;
CCP1CON:=%00000100;
PIR1.CCP1IF:=0;
end

else

begin
if ((PIR1.CCP1IF=1) and (bState=False)) then
begin
Hi(iHiDown):=CCPR1H;
Lo(iLoDown):=CCPR1L;
bState:=True;
CCP1CON:=%00000101;// on active front montant
PIR1.CCP1IF:=0;
end;
end;
end;
end;

procedure calcul_LargeurImpulsion;
begin
iResultDown:= iHiDown + iLoDown;
iResult:= iResultDown ;
iValueResult := (0.125) * iResult;
end;

procedure LcdRead;
begin
FloatToStr(iValueResult, AffResult);
Lcd_Out(1,1,AffResult + ' us' );
delay_ms(100);
WordToStr(iResult, AffResult2 );
Lcd_Out(2,1,AffResult2 + ' Pulse' );
end;

Begin
init;
While true do
begin
calcul_LargeurImpulsion;
LcdRead;
end;
end.

 

Protoype



Réalisé uniquement sur la platine EasyPIC 7.

Circuit imprimé


Aucun

Historiques


- 07/09/17
Première mise à disposition.