LO SCAFFALE DEGLI HOBBY

Appunti On Line

AVVERTENZE da leggere attentamente


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


schema

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



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.



All'indice principale | Al vecchio sito