>>> 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
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)