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.
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.
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.
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.
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 ?