Logiciels > Programmation PIC > Bases > MP > Activation d'une sortie

Dernière mise à jour : 29/07/2009

Présentation

Les exemples donnés ici montrent comment activer une ligne d'entrée / sortie configurée en sortie. Vous y verrez comment activer un relais ou allumer une led de façon continue (permanente) ou de façon alternée (clignotante). Avant de lire cette page, je vous conseille de commencer avec la page PIC - Bases - Configuration minimale, si ce n'est déjà fait.

Activer une sortie

Il n'est peut-être pas inutile de rappeler que presque toutes les pattes du ou des ports d'un PIC peuvent être configurées en entrée ou en sortie, grâce au registre TRIS. Les sorties que nous voulons activer doivent donc correspondre à des pattes qui ont été configurées en tant que sortie. On ne peut pas, de façon logicielle, modifier l'état logique "externe" d'une ligne qui est restée configurée en entrée. La première chose à faire consiste donc à décider quelles lignes doivent servir d'entrée et quelles lignes doivent servir de sortie. Pour l'exemple qui suit, nous allons utiliser trois lignes du port A (RA0, RA1 et RA4) pour commander deux leds et un relais.

pic_tuto_base_activation_sortie_001a

Remarques sur le schéma électronique
Les deux leds D1 et D2 ne sont pas câblées de la même façon, ceci pour montrer que l'on peut les allumer à partir d'un état logique haut ou d'un état logique bas. L'anode de la led D1 est en effet câblée côté +5 V, et sa cathode est reliée à la sortie RA0. Cette sortie RA0 doit donc fournir un état logique bas pour que la led D1 s'allume. Si cette sortie est à l'état logique haut, la led D1 reste éteinte. Pour D2, c'est l'inverse : son anode est reliée à la sortie RA1 et sa cathode est reliée à la masse. Elle s'allume donc avec une commande à l'état logique haut. Dans la pratique, vous pouvez toujours choisir la méthode de câblage qui vous convient le mieux, sachant que la "polarité" du signal de commande qui est envoyé sur la sortie désirée peut être laissée comme telle ou être inversée de façon très facile au niveau logiciel, à n'importe quel moment. Pour le relais RL1, une remarque s'impose : sur le schéma, on le voit câblé directement entre la sortie RA4 et le +5 V. Ce qui signifie que comme pour la led D1, son activation se fait avec une commande à l'état logique bas. Le câblage direct sur la sortie RA4 - sans passer par un transistor intermédiaire, n'est possible que si la bobine du relais ne consomme pas plus de 20 mA, le courant maximal de sortie du PIC étant limité à 25 mA. Pour permettre l'emploi d'un relais consommant plus de 20 mA, l'ajout d'un transistor est impératif (un simple 2N2222 ou 2N2907 - selon polarité désirée - suffit amplement) ! L'exemple de câblage qui suit montre comment ajouter un tel transistor.

pic_tuto_base_activation_sortie_001b

Du fait de la structure particulière de la sortie RA4 (qui est une sortie en collecteur ouvert), la résistance de rappel R1 est nécessaire pour polariser et faire conduire le transistor Q1, quand le transistor interne au PIC (de la sortie RA4) n'est pas passant. La commande du relais est donc inversée par rapport à la commande logique envoyée sur RA4 : si la commande est positive, le transistor interne conduit et bloque le transistor Q1, ce qui conduit au blocage du relais RL1. C'est le fonctionnement inverse de ce que l'on avait précédement avec le relais directement raccordé en sortie RA4. Avec le câblage du schéma suivant, qu'on ne peut pas reproduire pour la sortie RA4 (cela ne fonctionnerait pas), le relais est activé par une commande logique à l'état haut sur la ligne RA3.

pic_tuto_base_activation_sortie_001c

Notez que la "problématique" de la sortie en collecteur ouvert se pose avec une simple led, si on souhaite la raccorder sur la ligne RA4 : la brancher par rapport à la masse est tout simplement impossible, elle ne s'allumerait jamais.

pic_tuto_base_activation_sortie_001d

Ce problème ne se pose pas avec les autres sorties, c'est pourquoi le premier schéma, avec D1 sur RA0 et D2 sur RA1, est valide.

Remarques sur la configuration logicielle
Les lignes RA0, RA1 et RA4 doivent être configurées en tant que sortie, ce que l'on fait avec le registre TRIS, comme indiqué dans les lignes de code qui suivent :

program Test_16F628A_Activation_Sortie;

procedure Init;
begin
TRISA := %00000000; // toutes lignes du port A (RA0 à RA7) configurées en sorties
end;

// Main program
begin
Init;
end.


Dans le cas présent on ne s'est pas embêté, toutes les lignes du port A sont configurées en tant que sortie, ce qui bien sûr n'est absolument pas obligatoire. Si on veut utiliser en tant qu'entrées les lignes libres du port A, il suffit d'écrire la ligne suivante :

procedure Init;
begin
TRISA := %11101100; // RA0, RA1 et RA4 configurées en sorties, autres lignes en entrées
end;


L'activation des sorties

Nous y voici. Les lignes RA0, RA1 et RA4 ont été configurées en sortie, reste à voir comment changer leur état logique à la demande, de façon logicielle. Cela est en fait très simple, il suffit de comprendre que l'on peut accéder de façon individuelle aux diverses lignes d'un même port, et que cela est réalisable au travers de plusieurs méthodes. La première méthode consiste à utiliser le "mot clé" PORT, avec en suffixe la lettre qui correspond au port désiré. Par exemple PORTA pour le port A, PORTB pour le port B, etc. Et, tout comme cela avait été fait pour le registre TRIS (TRISA, TRISB ou autre), on peut attribuer une valeur logique individuelle pour l'ensemble des lignes du port en question. L'exemple qui suit montre comment "désactiver" les huit sorties du port A, c'est à dire leur donner à toutes l'état logique bas :

procedure Activation_Sorties;
begin
PORTA := %00000000; // RA0 à RA7 désactivées
end;


Dans le cas qui nous concerne, et pour RA1 et RA4, il s'agit d'une commande de désactivation des sorties, qui provoque l'extinction de la led D2 et le décollage (ou non-collage) du relais RL1. Mais pour le cas de RA0, la sortie est désactivée mais la led D1 s'allume, puisqu'elle "répond" à un état logique bas. Si on veut que les deux leds restent éteintes et qu'en même temps le relais reste désactivé, il faut écrire la ligne de code suivante :

procedure Activation_Sorties;
begin
PORTA := %00000001; // RA0 activée et RA1 à RA7 désactivées
end;


Cette façon d'activer ou de désactiver les sorties est interressante quand on veut intervenir sur toutes les sorties en même temps, mais elle n'est pas très pratique quand on veut modifier l'état logique d'une seule sortie, sans toucher aux autres. Pour piloter une sortie de façon totalement individuelle, il est préférable d'utiliser la méthode qui consiste à s'adresser directement et de manière exclusive à une ligne du port, grâce à son numéro. L'exemple suivant montre comment désactiver les sorties RA0 et RA4 et comment activer la sortie RA1 de façon indépendante, de façon à allumer les deux leds D1 et D2 et à faire coller le relais RL1.

procedure Activation_Sorties;
begin
PORTA.0 := 0; // désactivation de RA0 - allumage led D1
PORTA.1 := 1; // activation de RA1 - allumage led D2
 PORTA.4 := 0; // désactivation de RA4 - collage relais RL1
end;


Nous verrons plus loin que ce côté plus pratique peut dans certains cas réduire les performances globales, surtout quand une très grande rapidité d'exécution est attendue. Heureusement, dans bon nombre de cas, cette façon de faire est largement suffisante et donne pleinement satisfaction.
 

Faire "clignoter" une sortie

Faire clignoter une led sur une sortie est un exercice intéressant, car on sort du domaine statique pour entrer dans le domaine dynamique, celui des "choses qui bougent", où l'on voit rapidement si le programme que l'on a écrit est vraiment fonctionnel. Il peut en effet arriver qu'une mauvaise programmation d'un PIC conduise à un fonctionnement qui semble normal dans un premier temps, et qui se révèle perturbé par la suite. Le fait de faire clignoter une led avec une vitesse que l'on peut modifier est une bonne preuve que l'écriture de son code est réussie. C'est d'ailleurs une méthode que j'emploie assez couramment quand j'ai un doute sur la bonne configuration d'une patte d'un microcontrôleur supposée fonctionner en sortie : si j'arrive à la faire clignoter, c'est que la configuration est bonne ou pas loin de l'être. Le code suivant, complet et fort simple, permet de faire cligoter la led D1 reliée au port RA0 (premier schéma).

program Test_16F628A_activation_sorties;

procedure Init;
begin
TRISA := %00000000; // toutes lignes du port A (RA0 à RA7) configurées en sorties logiques
end;

procedure Activation_Sorties;
begin
PORTA.0 := 0; // désactivation de RA0 - allumage led D1
Delay_ms(500); // pause de 0,5 secondes
PORTA.0 := 1; // désactivation de RA0 - extinction led D1
Delay_ms(500); // pause de 0,5 secondes
end;

// Main program 
begin
Init;
while true do
begin
Activation_Sorties;
end;
end.


Avec le code qui précède, la fréquence de clignotement de la led est de 1 Hz, et il est facile d'accélerer ou de diminuer la cadence de clignotement simplement en changeant la valeur des retards introduits avec les commandes Delay_ms(xxx). Tel qu'il est écrit, ce code de quatre lignes permet de définir un temps d'allumage différent du temps d'extinction. Utile à savoir si on veut obtenir un effet de flash ou si on veut commencer à jouer avec des signaux de type PWM. Une écriture plus "économique" permet de faire clignoter la led avec un temps d'extinction égal au temps d'allumage (rapport cyclique de 50 %), c'est ce que montre le code suivant :

procedure Activation_Sorties;
begin
PORTA.0 := PORTA.0 xor 1; // basculement état logique de RA0
Delay_ms(500); // pause de 0,5 secondes
end;


Ici, la seule ligne de code "active" fait basculer la sortie RA0 dans l'état logique inverse de celui dans lequel elle se trouvait juste avant que la commande ne soit exécutée. La fonction XOR est en effet un OU exclusif, qui impose à la sortie concernée de prendre l'état logique haut uniquement si elle est à l'état logique bas, et inversement.

Petit test rigolo

Maintenant, un petit test interressant et rapide à mettre en pratique :

procedure Activation_Sorties;
begin
PORTA.0 := PORTA.0 xor 1; // basculement état logique de RA0
end;


Là, plus de retard ajouté avant de répeter la commande de changement d'état de la ligne RA0 (la ligne Delay_ms a disparue), le PIC travaille donc à sa vitesse maximale. Faites-le donc travailler à la vitesse d'horloge de 4 MHz, et mesurez la fréquence du signal obtenu sur cette sortie RA0. Vous trouverez une valeur voisine de 50 KHz. Maintenant, modifiez la procédure Activation_Sorties de sorte que l'action de changement d'état porte sur les cinq lignes RA0 à RA4 et non plus seulement sur la ligne RA0, et ce en modifiant l'état des lignes de façon individuelle.

procedure Activation_Sorties;
begin
PORTA.0 := PORTA.0 xor 1; // basculement état logique de RA0
PORTA.1 := PORTA.1 xor 1; // basculement état logique de RA1
PORTA.2 := PORTA.2 xor 1; // basculement état logique de RA2
PORTA.3 := PORTA.3 xor 1; // basculement état logique de RA3
PORTA.4 := PORTA.4 xor 1; // basculement état logique de RA4
end;


La fréquence du signal mesurée en RA0 est maintenant légèrement supérieure à 27 KHz. Et maintenant, modifiez la procédure Activation_Sorties de sorte que l'action de changement d'état porte sur les cinq lignes RA0 à RA4, mais cette fois en modifiant l'état des lignes de façon globale (avec une seule ligne de code) et non plus de façon individuelle (avec cinq lignes de code), comme le montre le code suivant :

procedure Activation_Sorties;
begin
PORTA := PORTA xor %00011111; // basculement état logique de RA0 à RA4
end;


La fréquence du signal mesurée en RA0 remonte à 50 KHz, pour un comportement final similaire (oscillation des cinq sorties du PIC). Interressant, non ?