LA PROGRAMMATION EN MIKROPASCAL

Mon cours a été introduit dans le manuel de cours pour les élèves du BAC technologie pour plus d'informations contactez moi sur le forum. Les schémas et les programmes sont téléchargeables sur le site sous la page téléchargement.

ABIDI Hatem

I-         La programmation en langage évolué :

Que ce soit par la méthode graphique ou en langage évolué, l'écriture du programme ainsi que sa mise au point doivent suivre le diagramme suivant :

étapes d'écriture du programme ainsi que sa mise au point d'un programme en mikropascal

Il faut  traduire le cahier des charges en une suite ordonnée d'actions que doit réaliser le processus de commande, cette suite d'opérations sera décomposée en actions élémentaires ou instructions c'est l'Algorithme. Par la suite il suffit de transformer cet algorithme en un langage évolué tel que le langage  PASCAL ou le langage C.

Dans la suite du cours on s'intéressera au langage PASCAL. (Compilateur Mikropascal de Mikroelektronika.) animation Flash Animation Flash sur Mikropascal

I-1-  Structure d'un programme :

Un programme est un texte que le compilateur va traduire en fichier hexadécimal. Alors il doit avoir une structure particulière.

Le texte d'un programme contient au moins trois parties.

Ne contient qu'une ligne; commence par le mot réservé « Program » et donne un nom au programme.

Elles permettent de définir les éléments utilisés dans le programme.
En effet on devra déclarer les variables utilisées pour permettre au compilateur d'effectuer les réservations de mémoire ainsi que les sous-programmes (Procédures et fonctions).

Commence par le mot réservé « Begin » et se termine par le mot réservé "End " suivi d'un point final. Ce qui suit ce "End" n'est pas pris en compte par le compilateur.
Entre "Begin" et "End" se trouvent les instructions à effectuer par le programme.

Algorithmique

Langage PASCAL

 

Algorithme NomAlgorithme ;

Variables

   Nomvariable  

Constantes                                     

   Nomconstante : Type =valeur ;                      

Début

.....

....

Fin.

Program NomProgramme ;

Var

  Nomvariable : Type ;

Const                                                  

  Nomconstante : Type = valeur ;                                               

Begin

.....

.....

End.

// entête

// déclaration

// Programme

// principal

I-2- Les Règles de bases :

·        Toutes instructions ou actions se terminent par un point virgule ;

·        Une ligne de commentaires doit commencer par "{" et se terminer par "}"  ou commence par "//".

·        Un bloc d'instructions commence par "Begin" et se termine par "End".

I-3- Les types de variables utilisées  en Mikropascal :

Type

Désignation

Taille

Rang

octet

byte

8....bit

0 .... 255

caractère

char

8....bit

0 .... 255

Mot

word

16....bit

0 .... 65535

Octet signé

short

8....bit

-128 .... 127

Entier

integer

16....bit

-32768 .... 32767

Entier long

longint

32....bit

-2147483648 .... 2147483647

Réel

real

32....bit

±1.17549435082 * 10-38 .. ±6.80564774407 * 1038

Tableau

Array[a..b] of type

 (b-a) éléments

Rang du type

Chaîne de caractères

string[n]

n caractère

0 .... 255

I-4- Les bases du compilateur Mikropascal :

Le décimal :             A=10 ;
L'hexadécimal            A=$0F ; ou A=0x0F ;
Le binaire               A=%11010100 ;

I-5-    les opérateurs arithmétiques et logiques :

Opérateurs arithmétiques

Opérateurs de comparaison

Opérateurs logiques

Opérateur

Opération

Opérateur

Opération

Opérateur

Opération

+

Addition

=

Egalité

AND

ET

-

Soustraction

<> 

Différent

OR

OU

*

Multiplication

Supérieur

XOR

OU exclusif

/

Division

Inférieur

NOT

NON

div

Division entière

<=

Inférieur ou égale

SHL

Décalage à gauche

mod

Reste de la division entière

>=

Supérieur ou égale

SHR

Décalage à droite

I-5-  Les structures usuelles :

a)    L'affectation :

C'est l'action d'attribuer une valeur à une variable.

Langage algorithmique

Langage PASCAL

a<== b+c

a :=b+c

b)    Les structures alternatives :

Langage algorithmique

Langage PASCAL

SI condition ALORS
  DEBUT
  Traitement ;
  ............;
  FINSI ;
IFcondition THEN
  BEGIN
  Traitement ;
  .........
  END;
SI condition ALORS
   DEBUT
   Traitement 1;
   ............;
   FIN 
SINON
   DEBUT
   Traitement 2;
   ............;
FINSI ;
IFcondition THEN
  BEGIN
  Traitement 1;
   ........;
  END
ELSE
  BEGIN
  Traitement 2;
  ........;
  END;
SELON expression
  Valeur_1 : action_ 1 ;
  ............;
  Valeur_n : action_n ;
  autrement : action_0 ;
FINSELON ;
CASE expression OF
   Valeur_1 :action_1;
   ............;
   Valeur_n : action _n ;
   ELSE action_0 ;
END;

c)    Les structures itératives ou répétitives :

Langage algorithmique

Langage PASCAL

I : entier ;
........;
POUR  I <Valeur initiale> 
             JUSQU'A <valeur finale> 
    FAIRE
      DEBUT
      Traitement ;
      ............;
      FINFAIRE ;
I: integer;
..........
FOR I:= <valeur initiale>  
                 TO <Valeur finale>
  DO
    BEGIN
    Traitement ;
    ........;
    END;
TANQUE condition FAIRE
      DEBUT
      Traitement ;
      ............;
      FINTANQUE ;
WHILE condition DO
     BEGIN
     Traitement ;
      ........;
     END;

d)    Les procédures et les fonctions

Une suite d'instructions peut être rassemblée en un bloc qui peut être appelé depuis plusieurs endroits d'un programme. Ceci donne lieu aux notions de sous programme appelé aussi  procédures ou fonctions.

Procédures

Ce sont des groupes d'instructions qui vont former une nouvelle instruction simple utilisable dans un programme. En Pascal il faut les définir avant de les utiliser. Ceci se fait en utilisant une structure similaire à celle d'un programme.

Entête

 Procedure Identificateur (Param1:Type1, Param2:Type2,...);

Identificateur est le nom de la procédure; Param1, Param2 ... sont des paramètres que le programme fournit à la procédure sous forme de constantes, de variables ou d'expressions; Type1, Type2 ... sont les types de ces paramètres.

Déclarations

Déclarations de constantes, types, variables utilisés à l'intérieur de la procédure

Corps de la procédure

 Begin
  Instruction1; Instruction2;......
 End;

Il s'agit des instructions exécutées par le programme à l'appel de la procédure. Une procédure peut appeler d'autres procédures définies avant elle. L'appel d'une procédure se fait en écrivant son nom suivi des paramètres nécessaires entre parenthèses.

Fonctions

Une fonction est une procédure qui devra fournir un résultat de type numérique ou chaîne de caractères. La définition se fait en utilisant une structure similaire à celle de la procédure.

Entête

Function Identificateur (Param1:Type1, Param2:Type2,...):Type_R;

Identificateur est le nom de la procédure; Param1, Param2 ... sont des paramètres que le programme fournit à la fonction sous forme de constantes, de variables ou d'expressions; Type1, Type2 ... sont les types de ces paramètres; Type_R est le type du résultat fourni par la fonction.

Déclarations

Déclarations de constantes, types, variables utilisés à l'intérieur de la fonction.

Corps de la fonction

 Begin
  Instruction1;  
  Instruction2;......
  Identificateur:=résultat;
 End;

Il s'agit des instructions exécutées par le programme à l'appel de la fonction. L'une de ces instructions doit fournir le résultat de la fonction en l'affectant au nom de la fonction. L'appel d'une fonction se fait en écrivant son nom suivi des paramètres nécessaires entre parenthèses. Elle représente une expression du type du résultat fourni.

I-6-  Les fonctions adaptées aux  microcontrôleurs PIC :

Le compilateur mikropascal apporte une large bibliothèque de procédures et fonctions adaptées aux microcontrôleurs de la famille PIC de MICROCHIP. Ces fonctions sont accessibles dans l'aide du logiciel néanmoins on va citer quelque une.

Fonctions / Procédures

Exemple

Setbit(port , bit) ;
Setbit(portB,2) ;     mettre la broche RB2 à 1
Clearbit(port , bit) ;
Clearbit(portB,5); mettre la broche RB5 à 0
Testbit(port , bit)
A :=testbit(portB,7);affecter à la variable A 
l'état de RB7 
Delay_ms(temps) ;
Delay_ms(150) ; attente de 150 ms
Button(port,bit,temps d'appui,état logique actif)
If Button(portA,2,10,1) then <Action 1> ;
On teste l'appui sur un bouton poussoir 
relié à la broche RA2 pendant 10 ms 
pour faire l'Action 1

II- Les interruptions

les interruption ?

II-1- Qu'est-ce qu'une interruption ?

Imaginez une conversation normale. Chaque interlocuteur prend la parole quand vient son tour de parler. Survient alors un évènement extérieur dont le traitement est urgent. Par exemple une voiture s'engage dans votre direction. Vous imaginez bien que votre interlocuteur ne va pas attendre la fin de votre phrase pour vous signaler le danger. Il va donc vous interrompre durant le cours normal de votre conversation; afin de pouvoir traiter immédiatement l'événement extérieur. Les interlocuteurs reprendront leur conversation où elle en était arrivée, sitôt le danger écarté. 

II-2- Les interruptions du microcontrôleur PIC16F84:

L'exécution d'une procédure d'interruption répond à un évènement qui peut être interne ou externe au microcontrôleur. L'appel d'une procédure d'interruption ne dépend pas du programme principal, mais elle l'interrompe  pendant son exécution.Dans une procédure d'interruption on ne peut pas appeler une autre procédure. Le compilateur Mikropascal utilise une directive spéciale pour le nom de la procédure (Procedure interrupt)  pour la différencier avec les autres procédures logicielles.Syntaxe :

Procedure interrupt;
Begin
       Instruction 1; 
       ............
       Instruction n;
End;

On notera que le 16F84 possède 4 sources d'interruptions:

Le registre INTCON est utilisé pour le contrôle et la gestion des interruptions.

INTCON:

GIE

EEIE

T0IE

INTE

RBIE

T0IF

INTF

RBIF

On s'intéressera uniquement à l'interruption externe via la broche RB0/INT, donc on aura à manipuler uniquement les trois bits suivants:

Le bit GIE, "Global lnterrupt Enable", mis à 1 autorise toutes les interruptions non masquées par leur bit individuel.

Le bit INTE, "Interrupt Enable", mis à 1, autorise les interruptions sur RB0/INI.

Le bit INTF, "Interrupt Flag", est un indicateur, il est mis à 1 si une interruption est générée sur RB0/INI. Il doit être remis à 0 par le logiciel dans le programme de traitement de l'interruption.

Pour activer l'interruption externe via la broche RB0/INT on doit affecter la valeur (90)H au registre INTCON :

INTCON:

1

0

0

1

0

0

0

0

= (90)H

Pour plus d'information sur les autres sources d'interruptions consultez le document constructeur  du microcontrôleur 16F84

RÉSUMÉ :

Structure générale d'un programme en Mikropascal pour le microcontrôleur 16F84A

Program nom_programme ;
  ....>Déclarations de constantes, types, variables utilisés dans le programme. 
  ....>Déclarations des procédures et fonctions utilisées dans le programme. 
Begin
  ....>Activation des interruptions utilisées
  ....>Configuration des entrées/sorties.
  ....>Initialisation des sorties utilisées.
while (1=1) do
    begin
         Instruction1;
         Instruction2;
         ......
    end ;
end.

Déclaration des variables et des constantes :

 Var nomvariable : type ;
 Const nomconstante : type = valeur ;

Déclaration d'une procédure:

Procedure Identificateur (Param1:Type1, Param2:Type2,...);
....>Déclarations de constantes, types, variables utilisés à l'intérieur de la procédure
 Begin
     Instruction1;
     Instruction2;
     ......
 End;

Déclaration d'une fonction:

Function Identificateur (Param1:Type1, Param2:Type2,...):Type_R;
....>Déclarations de constantes, types, variables utilisés à l'intérieur de la fonction.
  Begin
      Instruction1;
      Instruction2;......
      Identificateur:=résultat;
  End;

Déclaration d'une procédure d'interruption :

Procedure interrupt;
    Begin
         Instruction 1;
         ............;
        Instruction n;
        Mise à zéro de l'indicateur correspondant à la source d'interruption utilisée.
    End;

Méthodes usuelles de programmation :

Exercice 1: télécharger les fichiers [programme et simulation sous ISIS]

Traduction d'un GRAFCET de point de vue partie commande en un programme en Mikropascal pour le microcontrôleur PIC16F84A.- Soit le GRAFCET suivant :

Grafcet linéaire

- On vous donne le tableau  d'affectation des entrées/sorties pour le microcontrôleur PIC16F84A.

tableau d'affectation des e/s pour le PIC

Schéma de simulation :

Schéma de simulation du Grafcet linéaire sur PIC16F84

Travail demandé :

1/  Traduire le GRAFCET précédent en algorithme.

2/  Transformer cet  algorithme en programme en Mikropascal.Solution :

1/ L'algorithme :

Algorithme grafcet1 ;
  Variables  X0, X1, X2, X3 : octet ;  // Déclaration des étapes du GRAFCET.
 _DEBUT
|   TrisA <== $F8 ; // RA0, RA1, RA2  sont des sorties ; 
|                   //les autres broches sont des entrées.
|   TrisB <== $FF ;   // Toutes  les broches du  port B sont des entrées.
|   PortA <== 0 ;         // état initial des sorties.
|   X0 <==1 ;             // Initialement l'étape " X0 " est active.
|   X1 <== 0 ;            // Initialement l'étape " X1 " est non active.
|   X2 <== 0 ;            // Initialement l'étape " X2 " est non active.
|   X3 <== 0 ;            // Initialement l'étape " X3 " est non active.
|   TANQUE (1=1) FAIRE    // Boucle infinie.
|       _DEBUT
|      |  SI ((X0 =1) ET (Portb.0=1)) ALORS  // Condition de franchissement de la
|      |                                 // première transition qui est :
|      |                       // étape " X0 "  active et réceptivité " Dcy " vraie.
|      |                  _ DEBUT
|      |                 |      X0<== 0 ;  // Désactivation de l'étape " X0 ".
|      |                 |      X1<== 1 ; // Activation de l'étape " X1 ".
|      |                 |_ FINSI ;
|      |   SI ((X1 =1) ET (Portb.1=1)) ALORS  // Condition de franchissement de la
|      |                             // deuxième transition qui est :
|      |                          // étape " X1 "  active et réceptivité " a " vraie.
|      |                   _ DEBUT
|      |                  |      X1<== 0 ;  // Désactivation de l'étape " X1 ".
|      |                  |      X2<== 1 ;   // Activation de l'étape  "  X0 ".
|      |                  |_ FINSI ;
|      |   SI ((X2 =1) ET (Portb.2=1)) ALORS  // Condition de franchissement de la
|      |                        // troisième transition qui est :
|      |                   // étape " X2 "  active et réceptivité  " b " vraie.
|      |                  _ DEBUT
|      |                 |         X2<== 0 ;  // Désactivation de l'étape " X2 ".
|      |                 |         X3<== 1 ;  // Activation de l'étape " X3 ".
|      |                 |_ FINSI ;
|      |   SI ((X3 =1) ET (Portb.3=1)) ALORS   // Condition de franchissement de la
|      |                             // quatrième transition qui est :
|      |                       // étape " X3 " active et réceptivité " c " vraie.
|      |                  _DEBUT
|      |                 |      X3<== 0 ; // Désactivation de l'étape " X3 ".
|      |                 |      X0<== 1 ;  // Activation de l'étape " X0 ".
|      |                 |_FINSI ;
|      |   SI (X1=1) ALORS Porta.0 <==1 SINON Porta.0 <==0 ; FINSI; // 14M1 = X1.
|      |   SI (X2=1) ALORS Porta.1 <==1 SINON Porta.1 <==0 ; FINSI; // KM2 = X2.
|      |   SI (X3=1) ALORS Porta.2 <==1 SINON Porta.2 <==0 ; FINSI; // 12M1 = X3.
|      |_FINFAIRE ;
|_  FIN.

2/ Le programme :

program GRAFCET1;
Var  X0,X1,X2,X3:byte ;    // Déclaration des étapes du GRAFCET.
begin
TrisA := $F8 ;      // RA0,RA1,RA2 sont des sorties ;
                    // les autres broches sont des entrées.
TrisB := $FF ;     // Toutes  les broches du  port B sont des entrées.
PortA:= 0 ;         // état initial des sorties.
 X0:=1;             // Initialement l'étape " X0 " est active.
 X1:=0;             // Initialement l'étape " X1 " est non active.
 X2:=0;             // Initialement l'étape " X2 " est non active.
 X3:=0;             // Initialement l'étape " X3 " est non active.
 while (1=1) do     // Boucle infinie.
  begin
  if ((X0 =1) and (Portb.0=1)) then   // Condition de franchissement de la
                     // première transition qui est :
                 // étape " X0 "  active et réceptivité " Dcy " vraie.
                     begin
                     X0:=0;         // Désactivation de l'étape " X0 ".
                     X1:=1;         // Activation de l'étape " X1 ".
                     end ;
 if ((X1 =1) and (Portb.1=1)) then      // Condition de franchissement de la
                                     // deuxième transition qui est :
                   // étape " X1 "  active et réceptivité " a " vraie.
                     begin
                     X1:=0;        // Désactivation de l'étape " X1 ".
                     X2:=1;        // Activation de l'étape  "  X0 ".
                     end ;
  if ((X2 =1) and (Portb.2=1)) then     // Condition de franchissement de la
                                      // troisième transition qui est :
                  // étape " X2 "  active et réceptivité  " b " vraie.
                      begin
                      X2:=0;       // Désactivation de l'étape " X2 ".
                      X3:=1;       // Activation de l'étape " X3 ".
                      end ;
   if ((X3 =1) and (Portb.3=1)) then    // Condition de franchissement de la
                                       // quatrième transition qui est :
                  // étape " X3 " active et réceptivité " c " vraie.
                      begin
                      X3:=0 ;       // Désactivation de l'étape " X3 ".
                      X0:=1 ;       // Activation de l'étape " X0 ".
                      end ;
   if (X1=1) then Porta.0:=1  else Porta.0:= 0 ;        // 14M1 = X1.
   if (X2=1) then Porta.1:=1  else Porta.1:= 0 ;        // KM2 = X2.
   if (X3=1) then Porta.2:=1  else Porta.2:= 0 ;        // 12M1 = X3.
 end;
end.

Cas d'un Grafcet avec une temporisation ici : [programme et simulation sous ISIS]

Exercice 2:

Traduction des équations d'un système combinatoire en un programme en Mikropascal pour le microcontrôleur PIC16F84A.Soit les équations suivantes :

equations logiques

Schéma de simulation :

Schéma de simulation d'équations logiques

Travail demandé :

1/  Traduire les équations précédentes en algorithme.

2/  Transformer cet  algorithme en programme en Mikropascal.

Solution :  Première méthode :

1/ Algorithme :

Algorithme  EQUATIONS1;
_DEBUT
| trisA <== $FF;    // Tout le port A est configuré en entrée .
| trisB <== $E0;    // de RB0 à RB4 sorties les autres broches : entrées .
| portb <== 0;      // initialisation des sorties
| TANQUE  (1=1)  FAIRE    // boucle infinie 
|   _DEBUT 
|   |// équation de S0 : 
|   |  SI ((portA.0=1) ET (portA.1=1) ET ( portA.2=0)) ALORS 
|   |                      portb.0<==1 SINON portb.0 <== 0; FINSI ;
|   |//équation de S1 :
|   |  SI ((portA.1=1) XOR (portA.2=1)) ALORS  
|   |                      portb.1<==1 SINON portb.1 <== 0; FINSI ;
|   |//équation de S2 :
|   |  SI  ((portA.0=1) OU ((portA.1=1) ET (portA.2=0))) ALORS 
|   |                      portb.2<==1 SINON portb.2 <== 0; FINSI ;
|   |// équation de S3
|   |  SI  ((portA.1=0) ET (portA.2=0)) ALORS 
|   |                      portb.3<==1 SINON portb.3<==0; FINSI ;
|   |// équation de S4
|   |  SI ((portA.1=0) OU (portA.2=0)) ALORS 
|   |                      portb.4<==1 SINON portb.4<==0; FINSI ;
|   | _FINFAIRE;
|_FIN.

2/ Programme :

program EQUATIONS1;
 _begin
|trisA:=$FF;       // Tout le port A est configuré en entrée .
|trisB:=$E0;            // de RB0 à RB4 sorties les autres broches : entrées .
|portb:=0;              // initialisation des sorties
|while (1=1) do         // boucle infinie     
| _begin    // équation de S0 :     
||if((portA.0=1) and (portA.1=1) and ( portA.2=0)) then 
||                portb.0:=1 else portb.0:=0;    //équation de S1 :    
||if((portA.1=1) xor (portA.2=1))then 
||                portb.1:=1 else portb.1:=0;    //équation de S2 :     
||if ((portA.0=1) or ((portA.1=1) and (portA.2=0))) then 
||                portb.2:=1 else portb.2:=0;    // équation de S3    
||if ((portA.1=0) and (portA.2=0)) then 
||                portb.3:=1 else portb.3:=0;    // équation de S4    
||if((portA.1=0) or (portA.2=0))then 
||                portb.4:=1 else portb.4:=0;    
||_end;
|_end.

Deuxième méthode

1/ Algorithme :

Algorithme  EQUATIONS;
Variables  S1, S2, S3, S4, S5 : octet;   // déclaration des variables de sortie. 
 _ DEBUT| TrisA <== $FF;   // port A : entrée
| TrisB <== $E0;           //RB0, RB1, RB2, RB3, RB4 : sorties ;  RB5 ....RB7 : entrées
| Portb <== 0;             // initialisation des sortie 
| TANQUE (1=1)  FAIRE      // boucle infinie 
|       _ DEBUT
|      |    S1<==((portA.0) ET (portA.1) ET ((not portA.2)));    // équation de S1
|      |    S2<==((portA.1) OU exclusif  (portA.2));             // équation de S2
|      |    S3<==((portA.0) OU ((portA.1) ET ((not portA.2))));  // équation de S3
|      |    S4<== non ((portA.1) OU (portA.2));                  // équation de S4
|      |    S5<== non ((portA.1) ET (portA.2));                  // équation de S5
|      |
|      |    S1<==S1 ET $01;    // S1, S2, S3, S4, S5 sont de type octet (8 bits) 
|      |    S2<==S2 ET $01;    //  or on veut travailler avec un seul bit 
|      |    S3<==S3 ET $01;    // qui est le poids le plus faible (20)
|      |    S4<==S4 ET $01;    // alors il faut masquer les autres bits.
|      |    S5<==S5 ET $01;    // exp a (ocet) ; si a=0  alors non a=(11111111)2 
|      |
|      |    SI (S1=1) ALORS portb.0<==1 SINON portb.0<==0; FINSI;    // RB0 = S1.
|      |    SI (S2=1) ALORS portb.1<==1 SINON portb.1<==0; FINSI;    // RB0 = S1.
|      |    SI (S3=1) ALORS portb.2<==1 SINON portb.2<==0; FINSI;    // RB0 = S1.
|      |    SI (S4=1) ALORS portb.3<==1 SINON portb.3<==0; FINSI;    // RB0 = S1.
|      |    SI (S5=1) ALORS portb.4<==1 SINON portb.4<==0; FINSI;    // RB0 = S1.
|      |_FINFAIRE;
|_FIN.

2/  Programme :

program EQUATIONS;
Var S1,S2,S3,S4,S5 : byte;  // déclaration des variables de sortie. 
begin
trisA:=$FF;                 // port A : entrée.
trisB:=$E0;                 //RB0, RB1, RB2, RB3, RB4 : sorties ;  RB5 ....RB7 : entrées
portb:=0;                   // initialisation des sortie 
while (1=1) do              // boucle infinie      
  begin     
  S1:=((portA.0) and (portA.1) and ((not portA.2)));   // équation de S1     
  S2:=((portA.1) xor (portA.2));                       // équation de S2    
  S3:=((portA.0) or ((portA.1) and ((not portA.2)))); // équation de S3     
  S4:= not((portA.1) or (portA.2));      // équation de S4    
  S5:= not((portA.1) and (portA.2));    // équation de S5     
  S1:=S1 and $01;           // S1, S2, S3, S4, S5 sont de type octet (8 bits)      
  S2:=S2 and $01;           //  or on veut travailler avec un seul bit      
  S3:=S3 and $01;           // qui est le poids le plus faible (20)     
  S4:=S4 and $01;           // alors il faut masquer les autres bits.     
  S5:=S5 and $01;           // exp a (ocet) ; si a=0  alors non a=(11111111)2      
  if (S1=1) then portb.0:=1 else portb.0:=0;   // RB0 = S1.     
  if (S2=1) then portb.1:=1 else portb.1:=0;   // RB1 = S2.     
  if (S3=1) then portb.2:=1 else portb.2:=0;   // RB2 = S3.     
  if (S4=1) then portb.3:=1 else portb.3:=0;   // RB3 = S4.     
  if (S5=1) then portb.4:=1 else portb.4:=0;   // RB4 = S5.     
  end;
end.

Exercice 3:

Utilisation de l'interruption externe pour le comptage de pièces sur un tapis roulant dans un processus industriel.Principe de fonctionnement :

tapis roulant

-  Ce tapis roulant se trouve à la fin d'une chaine de fabrication de pièces mécaniques.-  Un capteur de proximité permet de compter le nombre de pièces fabriquées.-  Un bouton poussoir RZ permet de mettre le compteur à zéro.-  Le nombre de pièce comptées est affiché par un afficher LCD.Schéma de la carte de commande :

schéma du ompteur pour tapis roulant

Travail demandé :

1/  Traduire le fonctionnement de ce système par algorithme.2/  Transformer cet  algorithme en programme en Mikropascal.

Solution :

1/ L'algorithme :

Algorithme COMPTEUR;
Variables       
compteur : entier;  // déclaration de la variable de comptage : entier.           
nombre : chaine de caractère [12];  // déclaration d'une chaine de 12 caractères 
                                    // pour l'affichage. 
procédure interruption;     // sous programme d'interruption. 
   _DEBUT 
  |  intcon<==$90;    // validation de l'interruption RB0 
  |                   //et mise à zéro de son drapeau le bit INTF 
  |  compteur<==compteur+1; // incrémentation du compteur. 
  |_FIN;
 _DEBUT
|     lcd_config(portb,1,3,2,7,6,5,4);  
|                          //configuration de l'LCD doit toujours être avant la
|                          //configuration des registres TRISx 
|                          // lcd_config(le port, RS, E, RW, D7, D6, D5, D4) 
|     lcd_cmd(lcd_cursor_off);  // éteindre le curseur de l'afficheur LCD
|     TrisA<==$FF;   //portA entrée
|     TrisB<==$01;   // RB0 : entrée ; les autres broches : sorties pour l'LCD
|     intcon<==$90;  // activation de l'interruption externe RB0/INT
|     compteur<==0;  // initialisation du compteur.
|      lcd_out(1,1,'N.P =');   
|                //afficher sur la 1ere ligne et la 1ere colonne de l'LCD " N.P= ". 
|     TANQUE  (1=1)  FAIRE    // boucle infinie.
|           _DEBUT
|           |    inttostr (compteur,nombre); 
|           |     // changement de la variable " compteur " 
|           |          //en une chaine de caractère qui est " nombre ".
|           |    lcd_out(1,6,nombre); //afficher sur la 1ere ligne 
|           |                     //et la 6emme  colonne de l'LCD :" nombre ".
|           |    SI (porta.0=1) ALORS 
|           |            compteur<==0;FINSI;  // l'appui sur le bouton RZ 
|           |                                 // initialise le compteur.
|           |_FINFAIRE;
|_FIN.

2/ Le programme :

program COMPTEUR;
Var 
  compteur : integer;    // déclaration de la variable de comptage : entier.
  nombre : string[12];   // déclaration d'une chaine de caractère pour l'affichage.
procedure interrupt;     // sous programme d'interruption.        
  begin        
  intcon:=$90;  // validation de l'interruption RB0 
                //et mise à zéro de son drapeau le bit INTF        
  compteur:=compteur+1;  // incrémentation du compteur.        
  end;
begin
lcd_config(portb,1,3,2,7,6,5,4); //configuration de l'LCD doit toujours être avant la 
                          //configuration des registres TRISx   
                      // lcd_config(le port, RS, E, RW, D7, D6, D5, D4) 
lcd_cmd(lcd_cursor_off); // éteindre le curseur                   
TrisA:=$FF;              //portA entrée
TrisB:=$01;              // RB0 : entrée ; les autres broches : sorties pour l'LCD
intcon:=$90;             // activation de l'interruption externe RB0/INT
compteur:=0;             // initialisation du compteur.
lcd_out(1,1,'N.P =');    //afficher sur la 1ere ligne 
                         //et la 1ere colonne de l'LCD " N.P= ". 
while (1=1) do           // boucle infinie.            
            begin
            inttostr(compteur,nombre);  // changement de la variable " compteur "
                                   //en une chaine de caractère qui est " nombre ".
            lcd_out(1,6,nombre);   //afficher sur la 1ere ligne
                                   //et la 6emme  colonne de l'LCD :" nombre ".
            if (porta.0=1) then 
                   compteur:=0; // l'appui sur le bouton RZ initialise le compteur.
            end;
end.

Exercice 4: Extension d'un port  pour le microcontrôleur PIC16F84A.

On désire réaliser un compteur  modulo 100 en utilisant le microcontrôleur 16F84A et  deux afficheurs sept segments.

A / Etude préliminaire :

On vous donne le schéma suivant :

compteur 7 segments

1/ Ecrire le programme correspondant afin de réaliser un compteur modulo 10.

2/ Peut-on ajouter un deuxième afficheur sur les ports du microcontrôleur.

3/ Soit le schéma suivant :

bascule D

4/ Compléter les chronogrammes suivant :

chronogramme

B/ Extension du port B du microcontrôleur :

1/  On vous donne le circuit 74273, qui contient 8 bascules D avec horloge et remise à zéro  communes, proposer une solution  pour réaliser un compteur modulo 100 avec le PIC16F84A.

74273

2/  Ecrire le programme correspondant.

Solution :

A/

1/Première méthode :

7 segments
program COMPTEURMOD10a;
beginTrisb:=0;
portb:=0;
while (1=1) do
begin              //segments [ g f e d c b a]
portb:=%00111111 ; // chiffre 0
delay_ms(1000);    // attente d'une seconde
portb:=%00000110;  // chiffre 1
delay_ms(1000);
portb:=%01011011;  // chiffre 2
delay_ms(1000);
portb:=%01001111;  // chiffre 3
delay_ms(1000);
portb:=%01100110;  // chiffre 4
delay_ms(1000);
portb:=%01101101;  // chiffre 5
delay_ms(1000);
portb:=%01111101;  // chiffre 6
delay_ms(1000);
portb:=%00000111;  // chiffre 7
delay_ms(1000);
portb:=%01111111;  // chiffre 8
delay_ms(1000);
portb:=%01101111;  // chiffre 9
delay_ms(1000);
end;
end.
  

Deuxième méthode :

program COMPTEURMOD10b;
var i : integer;
const chiffre : array[10] of byte =(%00111111, %00000110, %01011011,%01001111, 
                                    %01100110, %01101101, %01111101, %00000111,
                                    %01111111,%01101111);
begin
Trisb:=0;
portb:=0;
while (1=1) do     
    begin     for i := 0 to 9 do  // compteur
               begin
               portb:=chiffre[i]; // affichage du chiffre
               delay_ms(1000); // attente d'une seconde
               end;
     end;
end.

2/Pour pouvoir contrôler deux afficheurs sept segments avec  un microcontrôleur il faut avoir au minimum 14 sorties sur ce dernier or le PIC16F84A ne possède que 13 entrée/sortie (8 sur le port B et 5 sur le port A) alors que faire ?

3/

chronogramme

B/1/

compteur modulo 100 avec PIC16F84

2/

program COMPTEURMOD100;
var i,j : integer;
const chiffre : array[10] of byte =(%00111111, %00000110, %01011011,%01001111, 
                                   %01100110, %01101101, %01111101, %00000111,
                                   %01111111,%01101111);
begin
Trisa:=$FC;
porta:=0;
Trisb:=0;
portb:=0;
while (1=1) do
     begin
     for j := 0 to 9 do  // compteur des dizaines
               begin
               portb:=chiffre[j]; // affichage du chiffre des dizaines
               porta.0:=1; //
               delay_ms(1); // Génération d'un front d'horloge sur RB0
               porta.0:=0;
                for i := 0 to 9 do  // compteur des unités
                       begin
                       portb:=chiffre[i]; // affichge du chiffre des unités
                       porta.1:=1;
                       delay_ms(1);  // Génération d'un front d'horloge sur RB1
                       porta.1:=0;
                        delay_ms(1000); // attente d'une seconde
                       end;
               end;
     end;
end.

Exercice 4:

Gestion d'un clavier matriciel par le microcontrôleur PIC16F84A.Soit le schéma suivant :

gestion clavie

Dans un premier lieu on s'intéressera au clavier.Schéma structurel d'un clavier 12 touches

clavier 16 touches

Le principe de ce type de clavier est simple en effet l'appui sur une touche réalise un contact direct entre la ligne et la colonne de cette touche. Pour pouvoir lire une touche appuyée par le microcontrôleur on procède comme suit:

On fait un balayage sur les colonnes c'est-à-dire on envoie les séquences suivantes  (100, 010, 001).On lit l'état des lignes sur 4 bits (A, B, C, D)On aura le tableau de correspondance suivant :

balayage du clavier

On désire afficher le code binaire correspondant à la touche appuyée sur les diodes led.

Travail demandé :

1/  Traduire le fonctionnement de ce système par algorithme.

2/  Transformer cet  algorithme en programme en Mikropascal.

Solution :

1/  Algorithme :

Algorithme clavier ;
  Variables
             T : octet ;
 _ Début
|      T<== 0 ;  {Initialisation de la variable T }
|      TRISA <== $F0 ; { RA0, RA1, RA2, RA3 : sorties ;    }
|       PortA <== 0 ;    {Initialisation du portA }
|      TRISB <== $F8 ;  {RB0, RB1, RB2 : sorties ; RB3, RB4, RB5, RB6, RB7 : entrées}
|      TANQUE  (1=1)  FAIRE {Boucle infinie}
|            _ Début 
|          |    PortB  <==  (00000001)2 ; {Première séquence}
|          |    Attente (10ms) ;                     
|          |    T<== PortB ; 
|          |    T<== T décalé à droite de 4 positions ;{Lecture de RB4, RB5, RB6 et RB7 }
|          |    SI T=8 ALORS T<== 10; FINSI;   {codage des touches }
|          |    SI T=4 ALORS T<== 7; FINSI;  
|          |    SI T=2 ALORS T<== 4; FINSI;            
|          |    SI T<> 0 ALORS PortA<==T ;{Afficher le numéro de la touche appuyée}
|          |                       FINSI;  {   sur le portA   } 
|          |    PortB <== (00000010)2 ;   {Deuxième séquence}
|          |    Attente (10ms) ; 
|          |    T <== PortB ; 
|          |    T <== T décalé à droite de 4 positions ;{Lecture de RB4, RB5, RB6 et RB7}
|          |    SI T=8 ALORS T <== 11 ; FINSI;          {codage des touches }
|          |    SI T=4 ALORS T <== 8 ; FINSI; 
|          |    SI T=2 ALORS T <== 5 ; FINSI; 
|          |    SI T=1 ALORS T<== 2 ;  FINSI;                                         
|          |    SI T<> 0 ALORS PortA<==T ;  {Afficher le numéro de la touche appuyée}   
|          |               FINSI;      {    sur le portA   }
|          |    PortB <== (00000100)2 ;       {Troisième séquence}
|          |    Attente (10ms) ;                     
|          |    T <== PortB ; 
|          |    T<==T décalé à droite de 4 positions ; {Lecture de RB4, RB5, RB6 et RB7}
|          |    SI T=8 ALORS T <== 12 ; FINSI; 
|          |    SI T=4 ALORS T <==  9  ; FINSI; 
|          |    SI T=2 ALORS T <==  6 ; FINSI; 
|          |    SI T=1 ALORS T <==  3 ;  FINSI;        {codage des touches }
|          |    SI T<> 0 ALORS PortA<==T ; FINSI;{Afficher le numéro de la touche appuyée}  
|          |                   {                   sur le portA    }
|          |_FinFaire ;
|_Fin.

 

2/  Programme

program clavier;
  Var T : byte ;
begin
T:= 0 ; {Initialisation de la variable T  }
TRISA := $F0 ;  { RA0, RA1, RA2, RA3 : sorties ;    }
portA:=0;     {Initialisation du portA }
TRISB :=$F8 ;{RB0, RB1, RB2 : sorties ; RB3, RB4, RB5, RB6, RB7 : entrées }
while  (1=1)  do       {Boucle infinie}
    begin
            PortB  := %00000001 ; {Première séquence}
            delay_ms(10) ;
            T:= PortB ;
            T:= T shr 4  ; {Lecture de RB4, RB5, RB6 et RB7}
            if T=8 then T:= 10;   {codage des touches }
            if T=4 then T:= 7;
            if T=2 then T:= 4;
            if T<> 0 then PortA:=T ;{Afficher le numéro 
                                     de la touche appuyée sur le portA  }
            PortB :=%00000010 ;    {Deuxième séquence}
            delay_ms(10) ;
            T := PortB ;
            T := T shr 4  ;   {Lecture de RB4, RB5, RB6 et RB7}
            if T=8 then T := 11 ;       {codage des touches }
            if T=4 then T := 8 ;
            if T=2 then T := 5 ;
            if T=1 then T := 2 ;
            if T<> 0 then PortA := T ;{Afficher le numéro de la 
                                        touche appuyée sur le portA   }
            PortB := %00000100 ;   {Troisième séquence}
            delay_ms(10) ;
            T := PortB ;
            T := T shr 4  ;        {Lecture de RB4, RB5, RB6 et RB7}
            if T=8 then T := 12 ;
            if T=4 then T :=  9 ;
            if T=2 then T :=  6 ;
            if T=1 then T :=  3 ;        {codage des touches }
            if T<> 0 then PortA := T ;{Afficher le numéro de la 
                                       touche appuyée sur le portA  }
    end ;
end.

Les librairies les plus utilisées en Mikropascal sont : 

- LCD Library 

- Keypad Library 

- Delays Library    

- Util Library

1/  LCD library :

Le compilateur MikroPascal fournit une bibliothèque pour communiquer avec l'afficheur LCD utilisé généralement en mode  4-bit

a) Lcd_Config :

Syntaxe

Lcd_Config (var port : byte; const. RS, EN, WR, D7, D6, D5, D4 : byte);

Description

 Initialiser l'afficheur LCD et définir les broches du microcontrôleur à relier à l'LCD.

Exemple 

Lcd_Config (PORTD,1,2,0,3,5,4,6);b)

b) Lcd_Init :

Syntaxe

Lcd_Init (var port : byte);

Description

Initialiser l'afficheur LCD avec  le PIC en spécifiant le port uniquement, le branchement de l'LCD avec le microcontrôleur est imposé par Mikropascal (consulter l'aide du logiciel) 

Exemple

 Lcd_Init (PORTB);

c) Lcd_Out :

Syntaxe

Lcd_Out (row, col : byte; var text : array[255] of char);

Description 

Ecrire un Texte sur l'afficheur LCD en indiquant sa position (ligne et colonne).

Exemple

 Ecrire  "Hello!" sur  LCD sur la ligne  1, colonne 3:Lcd_Out(1, 3, 'Hello!');

d) Lcd_Out_Cp :

Syntaxe

Lcd_Out_Cp(var text : array[255] of char);

Description 

Ecrire  le texte sur l'afficheur LCD à la position actuelle de curseur. 

Exemple

 Afficher " salut " à la position actuelle de curseur :Lcd_Out_Cp('salut');

e) Lcd_Chr :

Syntaxe

Lcd_Chr(row, col, character : byte);

Description 

Ecrire un Caractère sur l'LCD en indiquant sa position (ligne et colonne). 

Exemple

 Ecrire  "i" sur  LCD sur la ligne  2, colonne  3:Lcd_Chr(2, 3, 'i');

f) Lcd_Chr_Cp :

Syntaxe

Lcd_Chr_Cp(character : byte);

Description 

Ecrire un caractère sur l'afficheur LCD  à la position actuelle de curseur. 

Exemple

 Ecrire  "e" à la position actuelle du curseur.Lcd_Chr_Cp('e');

g) Lcd_Cmd :

Syntaxe

Lcd_Cmd (command : byte);

Description

Envoie une commande à l'afficheur LCD. La liste complète des commandes est la suivante :

LCD_FIRST_ROW             Déplacer le curseur  à la 1ère ligne
LCD_SECOND_ROW            Déplacer le curseur  à la 2 ème ligne
LCD_THIRD_ROW             Déplacer le curseur  à la 3 ème ligne
LCD_FOURTH_ROW            Déplacer le curseur  à la 4 ème ligne
LCD_CLEAR                 Effacer le contenu de l'afficheur
LCD LCD_RETURN_HOME       Retour du  Curseur  à la position initiale
 LCD_CURSOR_OFF           Arrêter  le curseur
LCD_MOVE_CURSOR_LEFT      Déplacer  le curseur à gauche
LCD_MOVE_CURSOR_RIGHT     Déplacer le curseur à droite
LCD_TURN_ON               Activer  l'affichage sur l'afficheur
LCDLCD_TURN_OFF           Arrêter l'affichage sur l'afficheur
LCDLCD_SHIFT_LEFT         Décalage de l'affichage à gauche
LCD_SHIFT_RIGHT           Décalage de l'affichage à droite

2/  Keypad Library :

Le MikroPascal fournit une bibliothèque pour travailler avec les claviers matriciels.

a) Keypad_Init :

Syntaxe

Keypad_Init(var port : word);

Description

Initialiser et préciser le port sur le quel est branché le clavier.

Exemple 

Keypad_Init(PORTB);

b) Keypad_Read :

Syntaxe

Keypad_Read : byte;

Description 

Vérifier si une touche est appuyée. La fonction renvoie 1 à 15, selon la touche appuyée, ou 0 si aucune touche n'est actionnée.

Exemple

 kp := Keypad_Read;

c) Keypad_Released :

Syntaxe

Keypad_Released :byte;

Description

L'appel de Keypad_Released génère une attente  jusqu'à ce qu'une touche soit appuyée et libérée. Une fois libérée, la fonction renvoie 1 à 15, selon la touche.

Exemples 

kp := Keypad_Released;

3/ Delays Library :

MikroPascal fournit une procédure pour créer des temporisations.

a) Delay_us :

Syntaxe

Delay_us(const time_in_us : word);

Description

Crée un  retard dont la durée en microsecondes est time_in_us (une constante). La gamme des constantes applicables dépend de la fréquence de l'oscillateur

Exemple

 Delay_us(10);  // Dix microsecondes

b) Delay_ms :

Syntaxe

Delay_ms(const time_in_ms : word);

Description

Crée un  retard dont la durée en millisecondes est time_in_ms (une constante). La gamme des constantes applicables dépend de la fréquence de l'oscillateur.

Exemple 

Delay_ms(1000);  //   une seconde.

c) Vdelay_ms :

Syntaxe

Vdelay_ms(time_in_ms : word);

Description

Crée un  retard  dont la durée en millisecondes est time_in_ms (une variable).

Exemple

Var Pause : integer ;

//.... 

Pause := 1000;

// ...

Vdelay_ms(pause);      //  pause d'une seconde

d) Delay_Cyc :

Syntaxe

Delay_Cyc(cycles_div_by_10 : byte);

Description

Crée un retard dont la durée est fonction de l'horloge du microcontrôleur.

Exemple 

Delay_Cyc(10); 

4/  Util Library

La bibliothèque 'util library'  contient des diverses routines utiles pour le développement de programmes.

Button

Syntaxe

Button (var port : byte; pin, time, active_state : byte) : byte;

Description

Les Paramètres (port)  et (pin)  indiquent l'endroit du bouton ; le paramètre temps d'appui nécessaire pour rendre le bouton actif ; le  paramètre active_state, peut être 0 ou 1,  il détermine si le bouton est ouvert au repos ou fermé au repos.

Exemple

while true do
begin 
   if Button(PORTB, 0, 1, 1) then oldstate := 255; 
   if oldstate and Button(PORTB, 0, 1, 0) then 
   begin   
      PORTD := not(PORTD);
      oldstate := 0; 
   end;
end;

5/ Autres fonctions intégrés:

Le compilateur mikroPascal fournit un ensemble de fonctions de service intégrées utiles. Les fonctions intégrées n'ont aucune condition spéciale ; vous pouvez les employer dans n'importe quelle partie de votre programme.

a)SetBit :

Syntaxe

SetBit(var register : byte; bit : byte);

Description

  Le Paramètre bit doit être une variable 

Exemple

 SetBit(PORTB, 2);  // RB2  =1 ;

b) ClearBit :

Syntaxe 

ClearBit(var register : byte; bit : byte);

Description

Le Paramètre bit doit être variable.

Exemple

ClearBit(PORTC, 7);  // RC7 =0 ;c)

c) TestBit :

Syntaxe

TestBit(var register : byte; bit : byte) : byte;

Description

Cette Fonction teste si le paramètre  bit est égal à 1. Si oui, la  fonction renvoie 1, si non elle  renvoie 0. Le  Paramètre bit doit être  variable. 

Exemple

flag := TestBit(PORTB, 2);   // flag =1 si RB2 =1  

cours Mikropascal microcontrôleur PIC programmation formation architecture compilateur Microchip transformation grafcet équation interruption registre INTCON TRIS variables fonction procedure erreur message LCD programme algorithme exercice

Révisé le :19-11-2017 www.technologuepro.com Facebook Twitter RSS