Dernière mise à jour :
08/09/2013
Présentation
Les exemples décrits ici montrent comment utiliser les
expandeurs de port PCF8574 et PCF8574A câblés sur un même bus I2C, en
association avec un microcontrôleur de type PIC 18F2420 utilisé en
maître. Une partie du texte explique comment adresser ces composants en
fonction de l'adresse affectée localement, au niveau physique des
PCF8574(A) eux-mêmes.
Electronique mise en oeuvre
Les exemples de code logiciel qui suivent montrent comment lire ou écrire une valeur tenant dans un octet
(valeur comprise entre 0 et 255), depuis ou vers un PCF8574 grâce à une
liaison bifilaire I2C.
Schéma électronique (001a) pour lecture et écriture
Pour la mise en pratique de ces exemples, le montage dont le schéma suit est mis en oeuvre.
Ce schéma peut sembler un peu complexe et touffu, mais il
permet de lire et d'écrire sur le même bus
I2C. Et si on y regarde bien, il n'y a finalement pas grand chose : 3
circuits intégrés, quelques interrupteurs, des leds et des réseaux de
résistances. En réalité et comme on peut s'en douter un peu, le PIC est
le seul
composant indispensable pour l'ensemble des opérations de lecture et
d'écriture. Les deux schémas suivant montrent les composants réellement
utilisés si on ne fait que lire (schéma 001b) ou que écrire (schéma
001c) les données au travres des PCF8574 via le bus I2C.
Schéma électronique (001b) pour lecture seulement
Cette partie de schéma permet de lire des données provenant du
PCF8574 (U1), de telle sorte que ses lignes d'entrées / sorties se
comportent en entrées.
L'état
logique des huit lignes du PCF8574 configurée en entrées sont
répliquées sur les lignes configurées en sorties du
PORTB du PIC. L'état logique de chaque ligne d'entrée du PCF8574 est
modifiable grâce aux interrupteurs regroupés dans le bloc DSW1.
Schéma électronique (001c) pour écriture seulement
Cette
partie de schéma permet d'écrire des données en direction du PCF8574A
(U2), de telle sorte que ses lignes d'entrées / sorties se comportent
en sorties.
L'état
que prennent les lignes du PCF8574A configurées en sortie dépend de
l'état logique des
lignes configurées en entrées du PORTA du PIC. L'état logique de
chaque ligne d'entrée du port A du PIC est modifiable grâce
aux interrupteurs regroupés dans le bloc DSW2.
Principe de fonctionnement général
Un
PCF8574 et un PCF8574A sont mis en parallèle sur le même bus I2C (voir
schéma complet 001a).
Ces deux composants fonctionnent exactement de la même façon, la
différence réside dans l'adresse de base avec lesquelles on doit les
adresser, qui est différente entre les deux. Pour le PCF8574, l'adresse
de base est $40, et pour le PCF8574A l'adresse de base est $70. Cette
histoire d'adresse ne doit pas vous faire peur, il s'agit juste d'un
moyen qui permet à chaque membre d'un réseau I2C de savoir si oui
ou non on s'adresse à lui. C'est une façon de faire le tri dans toutes
les données qui peuvent circuler sur le bus I2C et qui ne concernent
pas forcement tout le monde. Dans le cas présent il n'y a que deux
composants reliés sur le même bus I2C, mais on peut aller beaucoup plus
loin ! Les PCF8574 et PCF8574A disposent tous deux de trois entrées
d'adresse complémentaires, qui permettent de décaller leur adresse
d'affectation de base. Ces trois entrées d'adresse complémentaires
permettent huit combinaisons
possibles, ce qui correspond à huit valeurs d'adresses différentes.
Comme les adresses de base des PCF8574 et PCF8574A sont différentes, on
peut mettre en parallèle 8 circuits PCF8574 et 8 circuits PCF8574A - chacun avec une adresse différente, ce
qui permet de travailler avec 128 lignes de données distinctes (16 x 8
bits). Pour plus de détails, voir paragraphe "Adresses du PCF8574(A)"
après le descriptif du code logiciel.
Remarque
L'extension
du nombre de lignes de données peut egalement être
réalisée avec d'autres types de circuits non I2C. Si on veut juste
ajouter des lignes de sortie additionnelles, on peut par exemple
utiliser le CD4094 qui dispose de
8 sorties (exemples
Voltmètre 005 et
Horloge 002).
Et pour un usage en entrée ou sortie, on peut aussi utiliser des
multiplexeurs, à condition toutefois de disposer de plus de lignes pour
la commande de ces circuits (3 lignes ou plus selon le cas, exemple
Testeur de câble 001).
Si le nombre de lignes disponibles sur le PIC n'est que de deux, alors
les expandeurs de port PCF8574 (ou PCF8574A) constituent une solution vraiment
pratique et simple à mettre en oeuvre.
Lecture et écriture de données avec le PCF8574
Le code exemple qui suit comporte deux ensembles de routines :
- routines de lecture depuis les lignes d'extension du PCF8574
- routines d'écriture vers les lignes d'extension du PCF8574
A
Pas d'erreur dans les références des circuits utilisés, on met bien en oeuvre deux circuits électroniques PCF8574 différents :
- un PCF8574 pour utilisation en entrées additionnelles
- un PCF8574
A pour utilisation en sorties additionnelles
Ce
choix d'utilisation est arbitraire, on pourrait parfaitement faire
l'inverse, c'est-à-dire utiliser le PCF8574 pour disposer de sorties
additionnelles et utiliser le PCF8574A pour disposer d'entrées
additionnelles.
Logiciel
Le code ci-dessous correspond au programme complet.
program electronique_pic_tuto_base_i2c_pcf8574_001a;
const
cPCF8574_W = $40; // -> $4E;
cPCF8574_R = $41; // -> $4F;
cPCF8574A_W = $70; // -> $7E;
cPCF8574A_R = $71; // -> $7F;
var
Values: byte;
procedure Main_Init;
begin
CMCON := $07; // turn off comparators
ADCON1 := ADCON1 or $0F; // turn off analog inputs
TRISA := $FF; // inputs
TRISB := $00; // outputs
I2C1_Init(100000); // I2C comm init
end;
procedure PCF8574_Write;
begin
I2C1_Start; // signal START
I2C1_Wr(cPCF8574A_W); // addresse PCF8574A
Values := PORTA;
I2C1_Wr(Values); // écriture données
I2C1_Stop; // signal STOP
end;
procedure PCF8574_Read;
begin
I2C1_Start; // signal START
I2C1_Wr(cPCF8574_R); // addresse PCF8574
Values := I2C1_Rd(0); // lecture données
PORTB := Values;
I2C1_Stop; // signal STOP
end;
// programme principal
begin
Main_Init;
delay_ms(500);
while true do
begin
// lecture lignes PCF8574
PCF8574_Read;
Delay_ms(250);
// écriture sur lignes PCF8574A
PCF8574_Write;
Delay_ms(250);
end;
end.
Descriptif du logiciel
Procédure InitCette
routine d'initialisation générale, qui est appelée une seule fois au
moment de la mise sous tension du PIC, permet de définir l'orientation
des broches des ports A et B, grâce aux lignes TRISA et TRISB. La ligne
CMCON = 7 permet de désactiver le fonctionnement des comparateurs du
PIC. La ligne ADCON1 permet de désactiver les fonctions liées au
convertisseur Analogique / Numérique, toutes les lignes sont en effet
utilisées ici de façon logique. La ligne I2C1_Init permet d'initialiser
le module MSSP utilisé pour les fonctions de lecture / écriture sur bus
I2C.
Lecture de données en provenance du PCF8574 (lignes d'entrée additionnelles)
Les données présentes sur les lignes P0 à P7 du PCF8574 (U1) sont
répliquées sur le port B du PIC 18F2420 (U3). Si l'entrée P0 du PCF8574
(U1) est à l'état logique haut, alors la led connectée sur la broche
RB0 du PIC s'allume. Si l'entrée P1 du PCF8574 (U1) est à l'état
logique haut, c'est la led connectée sur la broche RB1 du PIC s'allume,
etc.
Ecriture de données vers le PCF8574 (lignes de sortie additionnelles)
Les données du port A du PIC 18F2420 (U3) sont répliquées sur les
lignes du PCF8574A (U2). Si la broche RA0 du PIC est à l'état logique
haut, alors la led connectée sur la broche P0 du PCF8574A (U2)
s'allume. Si la broche RA1 du PIC est à l'état logique haut, alors
c'est la led connectée sur la broche P1 du PCF8574A (U2) qui
s'allume, etc.
Programme principal
Dans le programme principal se déroule des actions qui se répètent
indéfiniment, grace à l'emploi d'une boucle infinie (qui ne s'arrête
jamais ca aucune condition n'impose son arrêt). Voici précisement ce qui est fait de façon répétée :
- on lit l'état logique des entrées additionnelles mises à disposition par le PCF8574
- on attend 250 ms sans rien faire
- on écrit sur les sorties additionnelles mises à disposition par le PCF8574A
- on attend 250 ms sans rien faire
Adresses des PCF8574 et PCF8574A
Chaque composant I2C esclave
possède une adresse qui lui est propre, et la portion de code suivante
(extraite du code complet vu ci-avant) précise à quelle numéro de rue
on doit frapper pour dialoguer avec les PCF8574(A).
const
cPCF8574_W = $40; // -> $4E;
cPCF8574_R = $41; // -> $4F;
cPCF8574A_W = $70; // -> $7E;
cPCF8574A_R = $71; // -> $7F;
Dans le cas présent, la définition des adresses est faite "en dur"
dans le code
logiciel via des constantes, avec des valeurs qui collent avec le
schéma proposé en début d'article. Mais dans certains cas vous pouvez
être ammené à modifier l'adresse de ces composants, ne serait-ce que si
vous en mettez plusieurs en parallèle, par exemple huit PCF8574 et huit
PCF8574A pour disposer de 128 lignes d'entrées / sorties. Dans ce cas,
les numéros d'adresses utilisées dans le logiciel du PIC doivent être
adaptées en fonction du composant avec lequel dialoguer. Le procédé
d'adressage est
assez simple à comprendre : les PCF8574 et PCF8574A disposent d'une
adresse fixe (qu'on
appelle adresse de base) et cette adresse fixe peut être décalée d'une
certaine valeur grâce aux broches d'adresse A0 à A2. Si vous branchez
en même temps plusieurs composants sur le même bus, alors chacun doit
avoir une adresse différentes parmi les huit possibles. Pour dialoguer
avec un PCF8574 configuré avec les broches A2..A0 à 000, vous
devez utiliser les adresses $40 et $41 dans le code. Pour
dialoguer avec un PCF8574A configuré avec les broches A2..A0 à 110,
alors vous devez utiliser les adresses $7C et $7D dans le
code.Vous
trouverez dans le tableau qui suit les adresses à utiliser
selon l'état logique donné aux broches A0 à A2, pour les PCF8574 et
PCF8574A.
A2 | A1 | A0 | PCF8574 Ecriture | PCF8574 Lecture | PCF8574A Ecriture | PCF8574A Lecture |
0 | 0 | 0 | $40 (064d) | $41 (065d) | $70 (112d) | $71 (113d) |
0 | 0 | 1 | $42 (066d) | $43 (067d) | $72 (114d) | $73 (115d) |
0 | 1 | 0 | $44 (068d) | $45 (069d) | $74 (116d) | $75 (117d) |
0 | 1 | 1 | $46 (070d) | $47 (071d) | $76 (118d) | $77 (119d) |
1 | 0 | 0 | $48 (072d) | $49 (073d) | $78 (120d) | $79 (121d) |
1 | 0 | 1 | $4A (074d) | $4B (075d) | $7A (122d) | $7B (123d) |
1 | 1 | 0 | $4C (076d) | $4D (077d) | $7C (124d) | $7D (125d) |
1 | 1 | 1 | $4E (078d) | $4F (079d) | $7E (126d) | $7F (127d) |
Pour
rappel, la valeur effective et complète de l'adresse est codée sur les sept bits
de poids fort de l'octet d'adresse envoyé sur le bus I2C, le dernier bit (de poids faible) étant reservé à
l'information de direction des données. Le texte qui
suit détaille la procédure qui a été suivie pour remplir le
tableau précédent. Les valeurs numériques notées selon la forme
xxxd sont exprimées en
décimal et les valeurs notées selon la forme
$xx sont exprimées en héxadécimal.
Adresse de base du PCF8574 :
0100 000x- bits 7 à 4 = adresse fixe =
0100 ($40 ou 064d)
- bits 3 à 1 = adresse variable =
000 ($00 ou 000d)
- bit 0 = bit de direction =
0 pour écriture ou
1 pour lecture
Pour
obtenir la valeur de l'adresse complète (part fixe plus part
variable), il suffit d'additionner les valeurs de ces trois
informations :
- pour écriture :
064d +
000d +
0 = 064d = $40
- pour lecture :
064d +
000d +
1 = 065d = $41
Exemple avec adresse variable du PCF8574 = 001 (A2 = 0, A1 = 0 et A0 = 1), alors on a :
- bits 7 à 4 = adresse fixe =
0100 ($40 ou 064d)
- bits 3 à 1 = adresse variable =
001 ($02 ou 002d)
- bit 0 = bit de direction =
0 pour écriture ou
1 pour lecture
Ce qui donne les valeurs suivantes pour l'adresse complète :
- pour écriture :
064d +
002d +
0 = 066d = $42
- pour lecture :
064d +
002d +
1 = 067d = $43
Exemple avec adresse variable du PCF8574 = 111 (A2 = 1, A1 = 1 et A0 = 1), alors on a :
- bits 7 à 4 = adresse fixe =
0100 ($40 ou 064d)
- bits 3 à 1 = adresse variable =
111 ($0E ou 014d)
- bit 0 = bit de direction =
0 pour écriture ou
1 pour lecture
Ce qui donne les valeurs suivantes pour l'adresse complète :
- pour écriture :
064d +
014d +
0 = 078d = $4E
- pour lecture :
064d +
014d +
1 = 079d = $4F
Notez
bien le décallage de 1 bit de la valeur d'adresse variable, idéal pour
se planter dans les calculs si on ne fait pas gaffe ! Et bien sûr, même
principe pour le PCF8574A.
Adresse de base du PCF8574A :
0111 000x- bits 7 à 4 = adresse fixe =
0111 ($70 ou 112d)
- bits 3 à 1 = adresse variable =
000 ($00 ou 000d)
- bit 0 = bit de direction =
0 pour écriture ou
1 pour lecture
Pour
obtenir la valeur de l'adresse complète (part fixe plus part variable),
il suffit d'additionner les valeurs de ces trois informations :
- pour écriture :
112d +
000d +
0 = 112d = $70
- pour lecture :
112d +
000d +
1 = 113d = $71
Exemple avec adresse variable du PCF8574A = 011 (A2 = 0, A1 = 1 et A0 = 1), alors on a :
- bits 7 à 4 = adresse fixe =
0111 ($70 ou 112d)
- bits 3 à 1 = adresse variable =
011 ($06 ou 006d)
- bit 0 = bit de direction =
0 pour écriture ou
1 pour lecture
Ce qui donne les valeurs suivantes pour l'adresse complète :
- pour écriture :
112d +
006d +
0 = 118d = $76
- pour lecture :
112d +
006d +
1 = 119d = $77
Exemple avec adresse variable du PCF8574A = 110 (A2 = 1, A1 = 1 et A0 = 0), alors on a :
- bits 7 à 4 = adresse fixe =
0111 ($70 ou 112d)
- bits 3 à 1 = adresse variable =
110 ($0C ou 012d)
- bit 0 = bit de direction =
0 pour écriture ou
1 pour lecture
Ce qui donne les valeurs suivantes pour l'adresse complète :
- pour écriture :
112d +
012d +
0 = 124d = $7C
- pour lecture :
112d +
012d +
1 = 125d = $7D
Quand
vous utilisez plusieurs PCF8574(A), vous pouvez utiliser les adresses
que vous voulez, l'important est que deux composants physiques ne
partagent pas la même. Mais vous pouvez adopter la même configuration
pour les broches A0..A2 s'il s'agit de PCF8574 et PCF8574A puisque leur
adresse de base (partie fixe) est différente. Il n'y a aucune
obligation d'utiliser des adresses contigues, ni de commencer avec
la part varable de l'adresse à 000. De même, la lecture des différents PCF8574(A) peut se
faire dans l'ordre que vous voulez. Vous pouvez ainsi câbler quatre
PCF8574(A) sur le même bus et utiliser les adresse suivantes :
- PCF8574 n°1 : adresses $44 (écriture) et $45 (lecture), broches A2..A0 = 010
- PCF8574 n°2 : adresses $4E (écriture) et $4F (lecture), broches A2..A0 = 111
- PCF8574A n°1 : adresses $7A (écriture) et $7B (lecture), broches A2..A0 = 101
- PCF8574A n°2 : adresses $7E (écriture) et $7F (lecture), broches A2..A0 = 111
Et lire en premier le PCF8574A n°1, ensuite le PCF8574 n°2, etc.
Historique
08/09/2013
- Correction erreur dans commentaires du code (mais code correct).
- Clarification des explications concernant les adresses à utiliser quand plusieurs PCF8574(A) sont utilisés en même temps.
25/04/2010
- Première mise à disposition