- Messaggi: 46
- Ringraziamenti ricevuti 1
I/O expander
13 Anni 3 Settimane fa #6
da crosby
Risposta da crosby al topic Re: I/O expander
Ciao
Finalmente sono riuscito a riesumare questo progettino sul port extender con 16 I/O MCP23017 che avevo a suo tempo sospeso prima delle vacanze. Sul port extender ho collegato due led uno sulla porta A (GPA1) e l’altro sulla porta B (GPB3) oltre che un pulsantino sulla porta A (GPA4) per cercare di ricreare una situazione il più incrociata possibile. All’inizio il programma fa lampeggiare i due led collegati con il MCP23017 oltre al LED8 sulla Freedom, alla fine con il pulsantino della breadboard controllo tutti i LED della Freedom.
Funziona!
Ho letto il datasheet del MCP23017, concentrando l’attenzione su 3 registri: IODIR, OLAT, GPIO.
Servono per impostare, scrivere, leggere dalle due porte, praticamente ho agito come se fossero i registri TRIS, LAT e PORT (perlomeno spero di aver interpretato la cosa in modo corretto).
I sorgenti sono molto ineleganti ma era per vedere prima se la cosa stava in piedi, c’è l’immagine del tutto, anche il cablaggio sulla breadboard non è proprio il massimo della vita …
Un saluto
Fabio Milano
/*
freedom.h
=========
*/
#include <p18f4550.h>
#pragma config FOSC = HS
#pragma config WDT = OFF, LVP = OFF, PBADEN = OFF
//
#define BT1 PORTBbits.RB4
#define BT2 PORTBbits.RB5
#define BT3 PORTBbits.RB6
#define BT4 PORTBbits.RB7
#define LED1 LATDbits.LATD0
#define LED2 LATDbits.LATD1
#define LED3 LATDbits.LATD2
#define LED4 LATDbits.LATD3
#define LED5 LATDbits.LATD4
#define LED6 LATDbits.LATD5
#define LED7 LATDbits.LATD6
#define LED8 LATDbits.LATD7
#define PORTA_LED LATD
#define BACK_LIGHT LATCbits.LATC1
#define BUZZER LATCbits.LATC0
#define SENSORE_LUCE ADC_CH0 //AN0
#define TRIMMER ADC_CH1 //AN1
#define SENSORE_TEMPERATURA ADC_CH2 //AN2
void InitFreedom();
void InitFreedom()
{
//ADCON1 = 0x0F; //imposta tutte le porte come I/O digitali
ADCON1 = 0b1100;
INTCON2bits.RBPU = 0; //abilita le R di pull-up sulla porta B
LATA = 0; TRISA = 0b00000111; //analogical input
LATB = 0; TRISB = 0b11110000; //four user buttons
LATC = 0; TRISC = 0b00000000;
LATD = 0; TRISD = 0b00000000; //leds + LCD
LATE = 0; TRISE = 0b00000000;
}
QUESTO E’ IL PROGRAMMA PRINCIPALE
#include "freedom.h"
#include <delays.h>
#include <i2c.h>
#define DEV_ADDR (0b0100) //device address for MCP23017 (same as PCF8574)
#define CHIP_ADDR (0b111) //chip address (pin A2, A1, A0 in this order)
#define SLAVE_DEVICE(rw) ( (DEV_ADDR << 4) | (CHIP_ADDR << 1) | rw ) //slave device to speak, first byte in I2C comunication, rw 0=wrire 1=read
// indirizzi delle porte
// utilizzare come indirizzi quelli relativi a IOCON.BANK = 0
#define IODIRA 0x00
#define OLATA 0x14 //0x0A
#define GPIOA 0x12
#define IODIRB 0x01
#define OLATB 0x15
#define GPIOB 0x13
void main()
{
unsigned char i;
unsigned char cancello; //ho poca fantasia nei nomi delle variabili
InitFreedom();
TRISBbits.TRISB0 = 1; //SDA
TRISBbits.TRISB1 = 0; //SCL
//inizializza il modulo I2C a 400KHz @20MHz
OpenI2C(MASTER, SLEW_ON);
SSPADD = 12;
// imposta la porta GPA come tutte uscite, GPA4 come ingresso
StartI2C();
WriteI2C(SLAVE_DEVICE(0));
WriteI2C(IODIRA);
WriteI2C(0b00010000); //GPA4 pulsantino
StopI2C();
StartI2C();
WriteI2C(SLAVE_DEVICE(0));
WriteI2C(OLATA);
cancello = 0x0;
WriteI2C(cancello);
StopI2C();
// imposta la porta GPB come tutte uscite
StartI2C();
WriteI2C(SLAVE_DEVICE(0));
WriteI2C(IODIRB);
WriteI2C(0b0);
StopI2C();
StartI2C();
WriteI2C(SLAVE_DEVICE(0));
WriteI2C(OLATB);
cancello = 0xFF;
WriteI2C(cancello);
StopI2C();
LED8 = 1;
for (i=0; i<12; i++) {
Delay10KTCYx(100);
LED8 = !LED8;
StartI2C();
WriteI2C(SLAVE_DEVICE(0));
WriteI2C(OLATA);
WriteI2C(cancello);
StopI2C();
cancello = ~cancello;
StartI2C();
WriteI2C(SLAVE_DEVICE(0));
WriteI2C(OLATB);
WriteI2C(cancello);
StopI2C();
}
while (1)
{
StartI2C();
WriteI2C(SLAVE_DEVICE(0));
WriteI2C(GPIOA);
RestartI2C();
WriteI2C(SLAVE_DEVICE(1));
cancello = ReadI2C();
StopI2C();
LED8 = ( (cancello & 0b00010000) == 0b00010000 );
LED7 = ( (cancello & 0b00010000) == 0b00010000 );
LED6 = ( (cancello & 0b00010000) == 0b00010000 );
LED5 = ( (cancello & 0b00010000) == 0b00010000 );
LED4 = ( (cancello & 0b00010000) == 0b00010000 );
LED3 = ( (cancello & 0b00010000) == 0b00010000 );
LED2 = ( (cancello & 0b00010000) == 0b00010000 );
LED1 = ( (cancello & 0b00010000) == 0b00010000 );
}
}
Finalmente sono riuscito a riesumare questo progettino sul port extender con 16 I/O MCP23017 che avevo a suo tempo sospeso prima delle vacanze. Sul port extender ho collegato due led uno sulla porta A (GPA1) e l’altro sulla porta B (GPB3) oltre che un pulsantino sulla porta A (GPA4) per cercare di ricreare una situazione il più incrociata possibile. All’inizio il programma fa lampeggiare i due led collegati con il MCP23017 oltre al LED8 sulla Freedom, alla fine con il pulsantino della breadboard controllo tutti i LED della Freedom.
Funziona!
Ho letto il datasheet del MCP23017, concentrando l’attenzione su 3 registri: IODIR, OLAT, GPIO.
Servono per impostare, scrivere, leggere dalle due porte, praticamente ho agito come se fossero i registri TRIS, LAT e PORT (perlomeno spero di aver interpretato la cosa in modo corretto).
I sorgenti sono molto ineleganti ma era per vedere prima se la cosa stava in piedi, c’è l’immagine del tutto, anche il cablaggio sulla breadboard non è proprio il massimo della vita …
Un saluto
Fabio Milano
/*
freedom.h
=========
*/
#include <p18f4550.h>
#pragma config FOSC = HS
#pragma config WDT = OFF, LVP = OFF, PBADEN = OFF
//
#define BT1 PORTBbits.RB4
#define BT2 PORTBbits.RB5
#define BT3 PORTBbits.RB6
#define BT4 PORTBbits.RB7
#define LED1 LATDbits.LATD0
#define LED2 LATDbits.LATD1
#define LED3 LATDbits.LATD2
#define LED4 LATDbits.LATD3
#define LED5 LATDbits.LATD4
#define LED6 LATDbits.LATD5
#define LED7 LATDbits.LATD6
#define LED8 LATDbits.LATD7
#define PORTA_LED LATD
#define BACK_LIGHT LATCbits.LATC1
#define BUZZER LATCbits.LATC0
#define SENSORE_LUCE ADC_CH0 //AN0
#define TRIMMER ADC_CH1 //AN1
#define SENSORE_TEMPERATURA ADC_CH2 //AN2
void InitFreedom();
void InitFreedom()
{
//ADCON1 = 0x0F; //imposta tutte le porte come I/O digitali
ADCON1 = 0b1100;
INTCON2bits.RBPU = 0; //abilita le R di pull-up sulla porta B
LATA = 0; TRISA = 0b00000111; //analogical input
LATB = 0; TRISB = 0b11110000; //four user buttons
LATC = 0; TRISC = 0b00000000;
LATD = 0; TRISD = 0b00000000; //leds + LCD
LATE = 0; TRISE = 0b00000000;
}
QUESTO E’ IL PROGRAMMA PRINCIPALE
#include "freedom.h"
#include <delays.h>
#include <i2c.h>
#define DEV_ADDR (0b0100) //device address for MCP23017 (same as PCF8574)
#define CHIP_ADDR (0b111) //chip address (pin A2, A1, A0 in this order)
#define SLAVE_DEVICE(rw) ( (DEV_ADDR << 4) | (CHIP_ADDR << 1) | rw ) //slave device to speak, first byte in I2C comunication, rw 0=wrire 1=read
// indirizzi delle porte
// utilizzare come indirizzi quelli relativi a IOCON.BANK = 0
#define IODIRA 0x00
#define OLATA 0x14 //0x0A
#define GPIOA 0x12
#define IODIRB 0x01
#define OLATB 0x15
#define GPIOB 0x13
void main()
{
unsigned char i;
unsigned char cancello; //ho poca fantasia nei nomi delle variabili
InitFreedom();
TRISBbits.TRISB0 = 1; //SDA
TRISBbits.TRISB1 = 0; //SCL
//inizializza il modulo I2C a 400KHz @20MHz
OpenI2C(MASTER, SLEW_ON);
SSPADD = 12;
// imposta la porta GPA come tutte uscite, GPA4 come ingresso
StartI2C();
WriteI2C(SLAVE_DEVICE(0));
WriteI2C(IODIRA);
WriteI2C(0b00010000); //GPA4 pulsantino
StopI2C();
StartI2C();
WriteI2C(SLAVE_DEVICE(0));
WriteI2C(OLATA);
cancello = 0x0;
WriteI2C(cancello);
StopI2C();
// imposta la porta GPB come tutte uscite
StartI2C();
WriteI2C(SLAVE_DEVICE(0));
WriteI2C(IODIRB);
WriteI2C(0b0);
StopI2C();
StartI2C();
WriteI2C(SLAVE_DEVICE(0));
WriteI2C(OLATB);
cancello = 0xFF;
WriteI2C(cancello);
StopI2C();
LED8 = 1;
for (i=0; i<12; i++) {
Delay10KTCYx(100);
LED8 = !LED8;
StartI2C();
WriteI2C(SLAVE_DEVICE(0));
WriteI2C(OLATA);
WriteI2C(cancello);
StopI2C();
cancello = ~cancello;
StartI2C();
WriteI2C(SLAVE_DEVICE(0));
WriteI2C(OLATB);
WriteI2C(cancello);
StopI2C();
}
while (1)
{
StartI2C();
WriteI2C(SLAVE_DEVICE(0));
WriteI2C(GPIOA);
RestartI2C();
WriteI2C(SLAVE_DEVICE(1));
cancello = ReadI2C();
StopI2C();
LED8 = ( (cancello & 0b00010000) == 0b00010000 );
LED7 = ( (cancello & 0b00010000) == 0b00010000 );
LED6 = ( (cancello & 0b00010000) == 0b00010000 );
LED5 = ( (cancello & 0b00010000) == 0b00010000 );
LED4 = ( (cancello & 0b00010000) == 0b00010000 );
LED3 = ( (cancello & 0b00010000) == 0b00010000 );
LED2 = ( (cancello & 0b00010000) == 0b00010000 );
LED1 = ( (cancello & 0b00010000) == 0b00010000 );
}
}
Si prega Accedi o Crea un account a partecipare alla conversazione.
- crosby
- Autore della discussione
- Senior Member
Riduci
Di più
13 Anni 3 Settimane fa #7
da Mauro Laurenti
Risposta da Mauro Laurenti al topic Re: I/O expander
...pensavo avessi lasciato stare!
Ottimo lavoro!
L'immagine mi fa pensare alla nuova scheda di espansione che e' appunto basata su breadboard, e serve per aiutare in queste applicazioni.
Vedo dal software che hai implementato la comunicazione I2C pezzo per pezzo.
Ti consiglio in un secondo momento di scrivere delle funzioni che integrano i comandi ti aiutera' a rileggere il tutto.
L'integrato e' interessante e pure in package PDIP...non si puo' chiedere altro!
Saluti,
Mauro
Ottimo lavoro!
L'immagine mi fa pensare alla nuova scheda di espansione che e' appunto basata su breadboard, e serve per aiutare in queste applicazioni.
Vedo dal software che hai implementato la comunicazione I2C pezzo per pezzo.
Ti consiglio in un secondo momento di scrivere delle funzioni che integrano i comandi ti aiutera' a rileggere il tutto.
L'integrato e' interessante e pure in package PDIP...non si puo' chiedere altro!
Saluti,
Mauro
Si prega Accedi o Crea un account a partecipare alla conversazione.
13 Anni 3 Settimane fa #8
da crosby
Risposta da crosby al topic Re: I/O expander
grazie
Si sono d'accordo adesso che mi sono "gasato" nel vedere che tutto funziona mi piacerebbe scrivere una bella libreria!
Si l'integrato è interessante prevede l'uso di altri registri che aggiungono altre funzionalità che mi prefiggo di studiare. Se qualcuno avesse fatto o volesse fare altre prove e avere uno scambio di idee è il benvenuto.
Studiando lo schema elettrico riportato della Freedom II ho notato che manca il diodo di protezione della tensione Vpp sulla circuiteria di reset, nella lista componenti della scheda tecnica c'è un diodo ma dovrebbe essere quello presente sull'alimentazione. Non è importante per proteggere dai 13 volt che arrivano dal PICkit2?
grazie
fabio milano
Si sono d'accordo adesso che mi sono "gasato" nel vedere che tutto funziona mi piacerebbe scrivere una bella libreria!
Si l'integrato è interessante prevede l'uso di altri registri che aggiungono altre funzionalità che mi prefiggo di studiare. Se qualcuno avesse fatto o volesse fare altre prove e avere uno scambio di idee è il benvenuto.
Studiando lo schema elettrico riportato della Freedom II ho notato che manca il diodo di protezione della tensione Vpp sulla circuiteria di reset, nella lista componenti della scheda tecnica c'è un diodo ma dovrebbe essere quello presente sull'alimentazione. Non è importante per proteggere dai 13 volt che arrivano dal PICkit2?
grazie
fabio milano
Si prega Accedi o Crea un account a partecipare alla conversazione.
- crosby
- Autore della discussione
- Senior Member
Riduci
Di più
- Messaggi: 46
- Ringraziamenti ricevuti 1
13 Anni 3 Settimane fa #9
da Mauro Laurenti
Risposta da Mauro Laurenti al topic Re: I/O expander
Salve Fabio,
il diodo D1 presente sulla scheda Freedom II e' utilizzato per proteggere la scheda da possibili inversioni di polarità.
La protezione di Vcc dai 13V provenienti dal programmatore e' data direttamente dal resistore R3 da 10Kohm presente sulla linea MCLR. Infatti anche con piccole correnti la caduta di tensione sulla resistenza e' tale da abbassare la tensione a valori dell'ordine di pochi volts.
Saluti,
Mauro
il diodo D1 presente sulla scheda Freedom II e' utilizzato per proteggere la scheda da possibili inversioni di polarità.
La protezione di Vcc dai 13V provenienti dal programmatore e' data direttamente dal resistore R3 da 10Kohm presente sulla linea MCLR. Infatti anche con piccole correnti la caduta di tensione sulla resistenza e' tale da abbassare la tensione a valori dell'ordine di pochi volts.
Saluti,
Mauro
Si prega Accedi o Crea un account a partecipare alla conversazione.
13 Anni 2 Settimane fa #10
da crosby
Risposta da crosby al topic Re: I/O expander
grazie infinite per il chiarimento
un saluto
fabio milano
un saluto
fabio milano
Si prega Accedi o Crea un account a partecipare alla conversazione.
- crosby
- Autore della discussione
- Senior Member
Riduci
Di più
- Messaggi: 46
- Ringraziamenti ricevuti 1
Moderatori: Mauro Laurenti, Pinna, StefA, Matteo Garia
Registrati al sito
Accedi a tutte le risorse e articoli non visibili pubblicamente, puoi registrarti con pochi passi.