Ci sono delle novità .
Sono riuscito a far parlare il Master. per ora però lo slave non riceve. Ovvero, se li collego assieme trovo il bus di I2C fermo, clock a 0v e data a 5V fissi.
Preso singolarmente, con le sole resistenze di pullup, il master manda in sequenza indirizzo a dati in questo modo:
dopo 200ms, come da codice, c'è una cosa analoga dove però la seconda parte è tutta alta, quindi non riceve niente, non vendo collegato l'altro pic. Come detto, se li collego entrambi la comunicazione si ferma.
void I2C_Master_Init(const unsigned long c)
{
SSPCON = 0b00101000;
SSPCON2 = 0;
SSPADD = (_XTAL_FREQ/(2*c))-1;
SSPSTAT = 0;
TRISC3 = 1; //Setting as input as given in datasheet
TRISC4 = 1; //Setting as input as given in datasheet
}
if ((SSPCONbits.SSPOV) || (SSPCONbits.WCOL))
{
z = SSPBUF; // Read the previous value to clear the buffer
SSPCONbits.SSPOV = 0; // Clear the overflow flag
SSPCONbits.WCOL = 0; // Clear the collision bit
SSPCONbits.CKP = 1;
}
I2C_Slave_Init(0x30); //Initialize as a I2C Slave with address 0x30
while(1);
}
Enea Ferriani
e.ferriani
postato il: 08.01.2018, alle ore 07:52
Questa era l'immagine che avevo allegato. Spero ora si veda.
Chiedo per l'ennesima volta, se è possibile, come si fa per modificare i post appena inviati? Non ho trovato istruzioni.
Enea Ferriani
picmicro675
postato il: 08.01.2018, alle ore 14:40
Benvenuto su Grix .
Non c'è anteprima ne redazione del messaggio inviato.
Ora ho preso le due codici. Faccio delle prove col simulatore e vediamo cosa non funziona.
Mi domando una cosa.... Il progetto è per uso personale oppure per lavoro ?
Nel primo caso, penso che si possa anche cercare un buon simulatore [icon]occhiolino[/code], ma credo che Altium (come hai scritto) non sia in grado di simulare due 16F873.
Da questo pezzo di codice, si potrà definire il dialogo che invia messaggi agli slave, che magari serve solo 5 al massimo 10 bytes per soddisfare la maggior parte di operazioni. Di questi bytes potrebbero benissimo esser in testo chiaro da leggere. Del tipo di programmazione che ho usato con http://www.grix.it/viewer.php?page=12722, vedendo la descrizione del programma.
Appena riesco leggo i link che hai messo. Cos'è il secondo? .7z?
Ad ogni modo ieri sera ho provato a fare qualcosa, ed ho visto che solo mettendo a zero SSPIE o commentandolo, il master riesce a comunicare, o meglio riesce a dire qualcosa seppur collegato allo slave. Me premendo il pulsante su RC1 del master non vedo variazioni sul led di RC0 sullo slave. Solo con l'oscilloscopio si vede il bit relativo al pulsante andare su.
Enea Ferriani
picmicro675
postato il: 09.01.2018, alle ore 18:47
Il secondo link in 7zip è quello che ho sistemato io per il micro di questa discussione. Contiene un sorgente per il master ed uno per uno slave. È un esempio di trasferire 32 bytes da master a slave e viceversa, ma quest'ultimo non riesce.
Anno nuovo, forum nuovo.
Mi sa che lascio.
e.ferriani
postato il: 09.01.2018, alle ore 23:48
Provo a spiegare quanto ho fatto fino ad ora.
Ho sistemato il codice in modo da renderlo più comprensibile almeno per me, che non sono un programmatore, ma lo faccio per gioco.
Ho messo dei commenti in modo da rendermi più chiaro il funzionamento e le varie chiamate a cosa si riferiscono. Magari prova a vedere se ho scritto delle cavolate.
Scritto così funziona, ho preso un po' del tuo codice, un po' di quello di microchip, ho rimesso in ordine le varie righe secondo quanto scritto ed interpretato dal manuale, spero di aver capito bene.
La prima cosa che ho fatto è stato muovere i bit della configuration word, fusibili.
Come avevo detto, fino a ieri, collegando i due pic, SDA->SDA e SCL->SCL, si vedeva un solo ciclo di lettura scrittura del master poi il nulla. Entrambi i segnali morti.
Una cosa che vedo, e vedevo anche ieri ed anche con lo slave scollegato, è che il primo blocco del master indirizzamento+scrittura funziona, nel senso che con l'oscilloscopio i bit confermano l'indirizzo 0x30 e, nel blocco dati, premendo il pulsante il relativo bit 1 sale quando viene premuto. Nel secondo blocco del master, l'indirizzo non è lo stesso, mi sembra un 0x31, cioè 00110001 con di seguito l'ACK. Di seguito è tutto alto.
Metto un video, così si capisce meglio, forse.
http://youtu.be/W56Pnrpu144 All'inizio si vede la pressione del pulsante.
Spero che il link funzioni.
Ho come l'impressione che il comando non venga letto dallo slave, e/o che il led non sia chiamato nel modo giusto. Dovrebbe accendersi alla pressione del pulsante sul master. Se riesco a fare andare questo poi potrò ritornare al resto del progetto.
short z;
void interrupt I2C_Slave_Read()
{
if(SSPIF == 1) // check to see if SSP interrupt
{
SSPCONbits.CKP = 0; // Clock Polarity Select bit CKP:
//0 = Holds clock low (clock stretch)
//(Used to ensure data setup time.)
if ((SSPCONbits.SSPOV) || (SSPCONbits.WCOL))
//SSPOV: Receive Overflow Indicator bit
//WCOL: Write Collision Detect bit
{
z = SSPBUF; // Legge il valore precedente del buffer
SSPCONbits.SSPOV = 0; // Receive Overflow Indicator bit SSPOV: 0 = No overflow
SSPCONbits.WCOL = 0; // Write Collision Detect bit WCOL: 0 = No collision
SSPCONbits.CKP = 1; // Clock Polarity Select bit CKP: 1 = Enable clock
}
if(!SSPSTATbits.D_nA && !SSPSTATbits.R_nW)
//D/A: Data/_Address bit (I2C mode only)
//R/W: Read/_Write bit Information (I2C mode only)
{
z = SSPBUF; // Legge il valore precedente del buffer
while(!BF);
RC0 = SSPBUF; // scrive in RC0 il buffer
SSPCONbits.CKP = 1; // Clock Polarity Select bit CKP: 1 = Enable clock
}
else if(!SSPSTATbits.D_nA && SSPSTATbits.R_nW)
//D/A: Data/_Address bit (I2C mode only)
//R/W: Read/_Write bit Information (I2C mode only)
{
z = SSPBUF; // Legge il valore precedente del buffer
BF = 0;
SSPBUF = RC1 ;
SSPCONbits.CKP = 1; // Clock Polarity Select bit CKP: 1 = Enable clock
while(SSPSTATbits.BF); //Buffer Full Status bit BF:
//1 = Data transmit in progress (does not include
//the ACK and STOP bits), SSPBUF is full
//0 = Data transmit complete (does not include the
//ACK and STOP bits), SSPBUF is empty
}
SSPIF = 0;
}
}
void I2C_Slave_Init()
{
TRISC3 = 1; //RC3 input per I2C
TRISC4 = 1; //RC4 input per I2C
SSPCON = 0b00110110; //era 0x36
SSPCON2bits.SEN = 1; //SEN: 1 = Initiate START condition on SDA and
//SCL pins. Automatically cleared by hardware.
//Clock stretching is enabled for a received
//address/data byte, ignoring the state of the
//SSPOV bit only if the BF bit = 0 the falling
//edge of SCL
SSPIF = 0; // Clear the serial port interrupt flag
BCLIF = 0; // Clear the bus collision interrupt flag
BCLIE = 1; // Enable bus collision interrupts
SSPIE = 1; // Enable serial port interrupts
PEIE = 1; // Enable peripheral interrupts
GIE = 1; // Enable global interrupts
void main()
{
INTCON = 0b00000000; //GIE: 0 = Disables all interrupts
//PEIE: 0 = Disables all peripheral interrupts
//T0IE: 0 = Disables the TMR0 interrupt
//INTE: 0 = Disables the RB0/INT external interrupt
//RBIE: 0 = Disables the RB port change interrupt
//T0IF: 0 = TMR0 register did not overflow
//INTF: 0 = The RB0/INT external interrupt did not occur
//RBIF: 0 = None of the RB7:RB4 pins have changed state
OPTION_REG = 0b11010111; //RBPU: 1 = PORTB pull-ups are disabled
//INTEDG: 1 = Interrupt on rising edge of RB0/INT pin
//T0CS: 0 = Internal instruction cycle clock (CLKOUT)
//T0SE: 1 = Increment on high-to-low transition on RA4/T0CKI pin
//PSA: 0 = Prescaler is assigned to the Timer0 module
//PS2÷PS0: 111 = TMR0-> 1:256, WDT Rate-> 1:128
nRBPU = 0; //Enable PORTB internal pull up resistor
// 0= USCITA
// 1= INGRESSO
TRISB = 0b11111111; //PORTB as input
TRISC0 = 0;
TRISC1 = 1;
TRISC7 = 0; //PORTC7 as output
I2C_Slave_Init(); //Initialize as a I2C Slave
while(1);
}
Enea Ferriani
picmicro675
postato il: 10.01.2018, alle ore 01:48
INTCON = 0 è superfluo, visto che cambia con I2C_Slave_Init().
Poi a me non corrisponde nRBPU = 0 , Non è una definizione valida. Anche questa superflua dato che hai già definito i bits in OPTION_REG.
Suppongo che RC0 = SSPBUF; non è corretto, non si può assegnare ad un bit il valore di un byte. Al limite prendi tutta la PORTC e quindi ripulisci i bit non interessati.
temp_port = SSPBUF; // scrive in temp_port il buffer
if (testbit(temp_port, 0) setbit(PORTC)
else clrbit(
Anno nuovo, forum nuovo.
Mi sa che lascio.
picmicro675
postato il: 10.01.2018, alle ore 01:54
Errore.
NTCON = 0 è superfluo, visto che cambia con I2C_Slave_Init().
Poi a me non corrisponde nRBPU = 0 , Non è una definizione valida. Anche questa superflua dato che hai già definito i bits in OPTION_REG.
Suppongo che RC0 = SSPBUF; non è corretto, non si può assegnare ad un bit il valore di un byte. Al limite prendi tutta la PORTC e quindi ripulisci i bit non interessati.
temp_port = SSPBUF; // scrive in temp_port il buffer
if (testbit(temp_port, 0) setbit(PORTC);
else clrbit(PORTC,0);
È solo uno stralcio di sorgente dove si legge e si scrive da SSBUF direttamente ai bit di PORTC. Se compili e vedi l' assembly, magari trovi che c'è un errore.
Altrimenti è probabile che vai ad influenzare RC4 e RC5 del bus I2C.
Anno nuovo, forum nuovo.
Mi sa che lascio.
e.ferriani
postato il: 10.01.2018, alle ore 06:48
INTCON E nRBPU se non li metto mi dava errore. Con le ultime modifiche vedo quanto contano...
RC0=SSPBUF credo che non vada bene infatti nel codice da cui sono partito era PORTD, tutta la porta,...ci ho provato ma non sapevo come scrivere.
Provo quello che mi hai passato, non ho mai scritto niente così. Semmai me lo faccio spiegare.
Il video è chiarificatore e ti torna con il codice, anche se è più x quanto fa il master?
Come utente anonimo puoi leggere il contenuto di questo forum ma per aprire una discussione
o per partecipare ad una discussione esistente devi essere registrato ed accedere al sito