I/O port expander MCP23017

>>> LINK A PAGINA AGGIORNATA <<<

  • .
  • .
  • .
  • .
  • .
  • .
  • .
  • .
  • .
  • .
  • .
  • .
  • .
  • .
  • .
  • .
  • .
  • .
  • .
  • .
  • .
  • .

L’integrato MCP23017 (datasheet) è un I/O port expander per bus i2c. Permette di controllare 16 ingressi/uscite singolarmente configurabili. I terminali di I/O (PA0..PA7 e PB..PB7) sono suddivisi in due porte a 8 bit (GPIOA e GPIOB).

Collegamento di prova

Port Expander MCP23017

Il terminale di reset (/RST) per le prove è stato collegato direttamente a Vcc. Volendolo utilizzare basta tenerlo a 5V con una resistenza di pull-up, e portarlo a livello basso (GND) per almeno 1 microsecondo.

 

Parametri ingressi/uscite

  • Ogni pin può gestire 25mA sia in source che in sink
  • Totale complessivo 150mA su GND e 125mA su Vcc
  • VIL = 0.2Vcc (1V a 5Vcc)
  • VIH = 0.8Vcc (4V a 5Vcc)
  • VOL = 0.6V
  • VOH = Vcc-0.7V (4.3V a 5Vcc)
  • Gli ingressi sono triggerati
  • Clamp ±20mA
  • Protezione ESD 4kV

Registri base

REGISTRO INDIRIZZO NOTA
IODIRA 0x00 direzione, bit 1=in 0=out
IODIRB 0x01  
GPPUA 0x0C pull-up, bit 1=pup 100kΩ
GPPUB 0x0D  
GPIOA 0x12 bit porta A
GPIOB 0x13 bit porta B
IPOLA 0x02 polarità, bit 1=inversione livello
IPOLB 0x03  

Programma Arduino di test:

Questo programma legge l’ingresso PB0, e a seconda del livello letto fa lampeggiare a frequenze diverse un LED collegato all’uscita PB7. I terminali SCK e SDA del bus i2c vanno collegati ai corrispondenti terminali di Arduino, che nel caso di Arduino2009/UNO sono rispettivamente A5 e A4.

//___________________________________________________________
//
//             MCP23017 test - By C.Fin 2018
//___________________________________________________________

#include <Wire.h>
//___________________________________________________________

#define MC_IODIRA  0x00
#define MC_IODIRB  0x01
#define MC_GPIOA   0x12
#define MC_GPIOB   0x13
#define MC_GPPUA   0x0C
#define MC_GPPUB   0x0D
//___________________________________________________________

void mcWrite(uint8_t mcAddr, uint8_t dataAddr, uint8_t data)
{
    Wire.beginTransmission(mcAddr);
    Wire.write(dataAddr);
    Wire.write(data);
    Wire.endTransmission();
}
//___________________________________________________________

uint8_t mcRead(uint8_t mcAddr, uint8_t dataAddr)
{
    Wire.beginTransmission(mcAddr);
    Wire.write(dataAddr);
    Wire.endTransmission();
    Wire.requestFrom(mcAddr, 1);
    return Wire.read();
}
//___________________________________________________________

void setup()
{
    Wire.begin();
    mcWrite(0x20, MC_IODIRA, 0b11111111); // PA tutti ingressi
    mcWrite(0x20, MC_GPPUA,  0b11111111); // tutti pull-up
    mcWrite(0x20, MC_IODIRB, 0b01111111); // PB7 uscita
    mcWrite(0x20, MC_GPPUB,  0b01111111);
}
//___________________________________________________________

void loop()
{
    static byte n = 0b10000000;

    mcWrite(0x20, MC_GPIOB, n ^= 0b10000000);

    if(mcRead(0x20, MC_GPIOB) & 1)
        delay(50);
    else
        delay(500);
}
//___________________________________________________________

L’uso di periferiche i2c è molto comodo, bastano due fili per connettere diverse periferiche (sensori, memorie, expander ecc), ma è piuttosto lento (più di mezzo millisecondo per ogni operazione). Se servono ingressi/uscite aggiuntivi più veloci si possono usare degli shift register.

(4/8/2018)

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *