Creative Commons BY-NC-ND 2.5Questo sito e tutto il suo contenuto sono distribuiti sotto la licenza Creative Commons Attribuzione - Non Commerciale - Non opere derivate 2.5 Italia e con le condizioni d'uso definite nel disclaimer: siete pregati di leggere entrambi questi documenti prima di usufruire dei contenuti di questo sito. Per alcuni contenuti è necessaria una registrazione gratuita: non è necessario pagare e non è necessario accumulare punteggi per accedere agli articoli e scaricare i sorgenti. Basta solo essere onesti. Se volete che questo sito continui a rimanere attivo, a contribuire ogni giorno alla diffusione della cultura libera, non copiate il materiale per ripubblicarlo in altri luoghi : chi fa questo è solo un miserabile e un perdente. Se volete partecipare su settorezero e rendere le vostre idee, i vostri progetti, fruibili da tutti senza limitazioni, come dovrebbe essere in un paese civile e acculturato, potete farlo tranquillamente.

Utilizzare l’ IO Expander PCF8574

Autore: Giovanni Bernardo | Data pubblicazione: 18 gennaio 2012
Categorie: PICmicro

A volte può ritenersi necessario, quando si è a corto di pin sul proprio microcontrollore, ricorrere a quei circuiti integrati chiamati IO Expander la cui funzione è palese: aumentare il numero di IO a disposizione. Abbiamo visto come è possibile aumentare il numero di uscite (nota: sole uscite) ricorrendo agli shift register (qui e qui). Un IO Expander permette di aggiungere sia ingressi che uscite, un unico IO Expander è in grado di aggiungere fino a 16 IO (es.: il PCA9555), tuttavia in questo articolo mi soffermo unicamente sul PCF8574, IO expander ad 8 bit, che pare essere quello più diffuso.

Il PCF8574 viene pilotato in I2C ed il suo utilizzo, avendo a disposizione delle semplici librerie per gestire la comunicazione I2C è davvero molto semplice. Il PCF8574 esiste in versione con o senza la lettera A finale: l’unica differenza tra i due è l’indirizzo I2C. Gli integrati hanno una parte di indirizzo fissa  più 3 bit variabili, che seguono il livello logico impostato sui pin contrassegnati con A0, A1 e A2:

Per cui, supponendo di impostare A0 e A1 a GND e A2 a +Vcc, l’indirizzo a 7 bit del PCF8574 sarà 0100100, al quale seguirà uno zero se vogliamo accedervi in modalità scrittura o un 1 se in modalità lettura. Gli IO sono i pin contrassegnati da P0 a P7. E’ anche presente un pin di interrupt (INT) a collettore aperto che genera un livello basso quando un qualsiasi pin configurato come ingresso ha una transizione.

Il PCF8574 può funzionare con una tensione di alimentazione da 2.5 a 6V.

Il funzionamento del PCF8574 è abbastanza particolare dal momento che gli IO sono QUASI-bidirezionali. Cosa significa? Quando gli IO vengono utilizzati come uscite, basta inviare unicamente un 1 o uno zero sul bit relativo per impostare l’uscita a livello alto o basso. Quando invece uno o più IO devono essere utilizzati come ingressi è necessario impostare il relativo IO a livello logico alto; un utilizzatore esterno può poi forzare il pin a livello alto o basso e quindi possiamo leggerlo. Il PCF8574 difatti non ha un registro di lettura/scrittura/impostazione dei pin. I pin vengono semplicemente impostati inviando un byte sul bus. Se inviamo, ad esempio, 00001111, impostiamo i pin P7-P4 come uscite a livello basso e i pin P3-P0 come uscite a livello alto ma anche come ingressi: sarà l’utilizzatore posto sui pin che se “legge” il pin, vedrà un livello logico alto mentre se “scrive” il pin lo può forzare a livello alto o basso inviandogli un segnale, senza pericolo di cortocircuiti se invia un livello basso. Sul datasheet difatti si legge chiaramente:

The device features an 8-bit quasi-bidirectional I/O port (P0–P7), including latched outputs with high-current drive capability for directly driving LEDs. Each quasi-bidirectional I/O can be used as an input or output without the use of a data-direction control signal. At power on, the I/Os are high. In this mode, only a current source to VCC is active. An additional strong pullup to VCC allows fast rising edges into heavily loaded outputs. This device turns on when an output is written high and is switched off by the negative edge of SCL. The I/Os should be high before being used as inputs.

Altri IO Expander, come il PCA9555 ad esempio, hanno invece un registro per impostare la direzione dei pin. Nel momento in cui vogliamo utilizzare alcuni IO come ingressi, quindi, dobbiamo ricordarci di impostarli a livello alto e successivamente eseguire la lettura.

Per scrivere sul PCF8574 utilizzeremo quindi la sequenza:

  1. Sequenza di Start
  2. Invio indirizzo PCF8574 in modalità scrittura
  3. Invio valore da impostare sulle 8 uscite
  4. Sequenza di Stop

Per leggere gli IO dal PCF8574, dopo esserci ricordati di impostarli a livello alto:

  1. Sequenza di Start
  2. Invio indirizzo PCF8574 in modalità scrittura
  3. Sequenza di Start ripetuto
  4. Invio indirizzo PCF8574 in modalità lettura
  5. Lettura
  6. Sequenza di stop

Dal valore ottenuto dalla lettura dovremmo ovviamente scartare tutti i bit relativi gli IO che stiamo utilizzando come uscite. La libreria inclusa nel download necessita delle routine I2C che potete scaricare in questa pagina e fa uso esclusivamente di due funzioni:

void ioexp_write(unsigned char address, unsigned char value);
unsigned char ioexp_read(unsigned char address);

La prima funzione accetta come primo parametro l’indirizzo a 7 bit del PCF8574 e come secondo il valore da assegnare agli IO. La seconda funzione esegue la lettura degli IO e la restituisce in formato unsigned char. Va sempre passato l’indirizzo a 7 bit dell’ IO expander.

Per poter utilizzare questa libreria, nel main dovete includere le librerie I2C di settorezero e le librerie pcf8574:

#include "i2c.c"
#include "ioexp.c"

Dopodichè vi conviene definire con una costante l’indirizzo del vostro PCF8574, esempio:

#define IOEXP_ADDR 0x20	// indirizzo a 7 bit del PCF8574 con A0,A1 e A2 collegati a GND

Ricordatevi quindi di inizializzare il modulo I2C nel main:

I2cInitMaster(); // avvio il modulo MSSP in modalità I2C master

Dopodichè qui ci sono alcuni esempi di utilizzo:

Impostazione P7-P0 come uscite a livello basso

ioexp_write(IOEXP_ADDR, 0b00000000);

Impostazione P7-P4 come uscite a livello basso e P3-P0 come uscite a livello alto/ingressi

ioexp_write(IOEXP_ADDR, 0b00001111);

Lettura di P0 e P1 impostati come ingressi

ioexp_write(IOEXP_ADDR, 0b00000011); // imposto P0 e P1 come ingressi
unsigned char value; // questa variabile conterrà il valore letto dall' IO expander
value=ioexp_read(IOEXP_ADDR);
value &= 0b00000011; // azzero i bit P7-P2 per sicurezza. Ora value contiene solo il valore di P0+P1

Nel caso in cui la scrittura potrebbe influenzare lo stato di altre uscite che non vogliamo toccare, è bene utilizzare una variabile che contenga lo stato degli IO ed una maschera. Ad esempio:

unsigned char iovalue=0b00110011; // P7,P6,P3 e P2 come uscite a livello basso, P5,P4,P1,P0 come uscite a livello alto o ingressi
ioexp_write(IOEXP_ADDR, iovalue);
// a questo punto voglio utilizzare anche P7 e P6 come ingressi ma non voglio spostare gli altri IO:
unsigned char newvalue = iovalue | (0b11000000); // newvalue ora vale 0b11110011
ioexp_write(IOEXP_ADDR, newvalue);
unsigned char value;
value=ioexp_read(IOEXP_ADDR); // leggo lo stato delle porte del PCF8574
value &= 0b11000000; // value ora contiene il valore di P6+P7
ioexp_write(IOEXP_ADDR, iovalue); // riporto gli IO com'erano prima

In tutto questo ci dobbiamo assicurare che gli utilizzatori posti sulle porte configurati come ingressi (uscite a livello alto) poi non corrano il rischio di mandare tutto in corto circuito se impostiamo quegli IO come uscite a livello basso.

Download

PDFRoutine per utilizzo IO Expander PCF8574 (4.13 kB - 146 downloads)

Links utili

L'articolo ti è piaciuto o ti è stato utile per risolvere un problema? SettoreZero è realizzato soltanto contenuti originali: tutti gli articoli sono curati con passione dagli autori e nulla viene copiato da altri siti. Supporta e mantieni in vita SettoreZero con una donazione: basta soltanto un caffè o una birra. Puoi supportare SettoreZero anche con uno dei progetti elencati nella sezione servizi o partecipare anche tu con un tuo articolo/progetto personale.

Se desiderate che SettoreZero continui a rimanere gratuito e fruibile da tutti, non copiate il nostro materiale e segnalateci se qualcuno lo fa.

Puoi andare alla fine dell'articolo e lasciare un commento. I trackback e i ping non sono attualmente consentiti.

  1. #1 da lodi12 il 3 febbraio 2012

    Ciao Giovanni,
    sfogliando il datasheet del PCF8574 (ormai non mi piace più solo leggere i tuoi articoli, voglio vedere anche come fai a “trovare” le cose :D ) ho notato che per la lettura delle porte non è necessario mandare l’indirizzo in modalità scrittura e fare il restart…ho provato su simulatore togliendo i due punti e sembra funzionare; per quale motivo gli hai messi? maggiore sicurezza?

  2. #3 da matteo garia il 24 dicembre 2012

    Ciao,
    Sto provando ad utilizzare questa libreria su PIC16F877A, insieme alla libreria i2c.
    Non riesco a leggere alcun dato dal PCF8574 poichè l’esecuzione si blocca sul controllo del bit SSPIF.
    Quando viene chiamata la funzione ioexp_read il pic invia l’indirizzo, poi durante l’invio dell’indirizzo in lettura si blocca.
    Hai per caso già incontrato questo problema?

    ps. ho notato alcuni errori “palesi” nella libreria: sono voluti per evitare copiature o sono sfuggiti?

    Buone Feste
    Matteo

  3. #4 da matteo garia il 24 dicembre 2012

    Aggiungo una novità:

    Rallentando il bus (inserendo a mano nel registro SSPADD un valore più alto) il tutto funziona.
    Mi viene il dubbio che sia un problema di capacità parassite sul bus, dovuto alle piste lunghe (scheda Freedom 2 + breadboard)

  4. #5 da enzocavallaro il 7 maggio 2013

    Chiedo scusa ma da dove posso scaricare “pcf8574.h” che è incluso nella routine per utilizzo IO Expander PCF8574 ?
    Grazie

Devi essere collegato per lasciare un commento.

  1. Ancora nessun trackback
settorezero.com e il logo Zroid™ ©2007÷2013 Giovanni Bernardo - E' vietata la copia e la distribuzione anche parziale dei contenuti di questo sito web senza l'esplicito consenso dell'autore.
I contenuti di settorezero.com sono distribuiti sotto una licenza Creative Commons Attribuzione-Non Commerciale-Non Opere derivate 2.5 Italia a cui vanno aggiunte le condizioni d'uso definite nel disclaimer.
settorezero.com e tutti i suoi contenuti sono tutelati dalla legge sul diritto d'autore per cui i trasgressori sono perseguibili a norma di legge.
Creative Commons BY-NC-ND 2.5
Il tema di questo sito è basato sul tema Fusion per wordpress, realizzato originariamente da digitalnature e fa uso del plugin Wassup per il computo delle statistiche. Per contattare l'autore siete pregati di utilizzare la sezione contatti.
Per essere aggiornato con tutte le novità di settorezero.com seguici anche anche su Facebook Twitter Tumblr Blogspot Youtube.