Cos'è ElectroYou | Login Iscriviti

ElectroYou - la comunità dei professionisti del mondo elettrico

Problema interrupt su linea SPI con pic18f46k22

Raccolta di codici sorgenti

Moderatore: Foto UtentePaolino

0
voti

[1] Problema interrupt su linea SPI con pic18f46k22

Messaggioda Foto Utentespivo » 14 feb 2016, 18:27

Ciao a tutti, ho un problemino di software un po' difficile da spiegare.

Questo che allego è parte del codice per un micro pic18f46k22, il codice dovrebbe fare questo:

Aspettare che un raspberry lo interroghi tramite connessione spi (spi2 nel mio caso particolare), se il primo byte è 0x61 riceve 30 byte e invia i 30 che lui si era preparato.
Quando torna al ciclo infinito se i il primo dei trenta era 0x61 e l'ultimo 0x62 aggirona i dati per il prossimo invio.
Codice: Seleziona tutto
void main(void)
{
    ConfigureOscillator();
    ConfigurePort();
    ConfigureSPI1();
    ConfigureMCPD();
   

    // Visualizza accensione
    LEDrosso = 1;
    LEDverde = 1;

    //CONFIGURAZIONE SPI2 SLAVE
    SSP2CON1bits.SSPEN = 1;
    SSP2CON1bits.SSPM = 0b0100;
    SSP2CON1bits.CKP = 0;

    SSP2STATbits.CKE = 1;
    SSP2STATbits.SMP = 0;

    SSP2BUF = 0;

    //CONFIGURAZIONE INTERRUPT
    RCONbits.IPEN = 1;

    PIE3bits.SSP2IE = 1;
    IPR3bits.SSP2IP = 1;
    PIR3bits.SSP2IF = 0;

    //Prepara le variabili prima dell'avvio
    ch_num = 0;
    SistemazioneDati();

    for (i=0;i<100; i++) __delay_ms(10);
    LEDrosso = 0;
    LEDverde = 0;

    //ATTIVA INTERRUPT
    INTCONbits.GIE = 1;


    while(1)
    {


         if (ch_in[0] == 0x61 && ch_in[29] == 0x62){
             ch_num = 0;
             ch_in[0] = 0;
             ch_in[29] = 0;
                // invia dati a mm5450 1
                MM_5450_1();
                // Lampeggio led dopo l'invio dei dati
                LEDverde = ~LEDverde;
                // Sistemazione dati prima del prossimo invio
                SistemazioneDati();
         }


    // Rilevamento MCP23S17 1
    MCPD_1=0; //Indica allo slave che i dati in arrivo
        SSP1BUF=0b01000001; //indirizzo + read
        while(!SSP1IF);
        ch_canc=SSP1BUF;
        SSP1IF=0;
        SSP1BUF=0x12; //Invio GPIOA
        while(!SSP1IF);
        ch_canc=SSP1BUF;
        SSP1IF=0;
        SSP1BUF=0x00;
        while(!SSP1IF);
        ch_out[3]&=SSP1BUF;
        SSP1IF=0;
    MCPD_1=1; //Fine comunicazione
    MCPD_1=0; //Inizio comunicazione
        SSP1BUF=0b01000001; //indirizzo + read
        while(!SSP1IF);
        ch_canc=SSP1BUF;
        SSP1IF=0;
        SSP1BUF=0x13; //Invio GPIOB
        while(!SSP1IF);
        ch_canc=SSP1BUF;
        SSP1IF=0;
        SSP1BUF=0x00;
        while(!SSP1IF);
        ch_out[4]&=SSP1BUF;
        SSP1IF=0;
    MCPD_1=1; //Fine comunicazione

        for (i=0;i<2; i++) __delay_ms(1);
        LEDrosso = ~LEDrosso;
    }
}

void interrupt high_isr(void)
{
    if (PIR3bits.SSP2IF)
    {
        ch_in[ch_num] = SSP2BUF;
        SSP2BUF = ch_out[ch_num];
        ch_num++;
       
        if (ch_in[0] != 0x61 || ch_num > 30) ch_num = 0;

    PIR3bits.SSP2IF = 0; //reset interrupt
    }
}

Mentre aspetta di essere inerrogato da raspberry il PIC continua a leggre un mcp23s17 per monitorare degli ingressi digitali e fa lampeggiare freneticamente il LEDrosso.

Prima che inserissi la parte di codice relativa all'mcp23s17 tutto funzionava bene. (raspberry conta se una connessione da errore e in due settimane di connessioni continue non ha mai dato errori)

Con il codice postato, da un centinaio di errori al giorno.

Ho provato anche ad eliminare il lampeggio del LEDrosso, (che avevo inserito all'inizio per sapere se il PIC era acceso). Se elimino questa parte di codice da una marea di errori.

Spero di essermi spiegato, non so nemmeno come intitolare il post, grazie caio Ivo
Ultima modifica di Foto UtenteWALTERmwp il 15 feb 2016, 0:31, modificato 1 volta in totale.
Motivazione: Esteso il titolo
Avatar utente
Foto Utentespivo
375 1 12
Frequentatore
Frequentatore
 
Messaggi: 179
Iscritto il: 19 dic 2012, 21:29

2
voti

[2] Re: Problema interrupt

Messaggioda Foto UtenteGuidoB » 14 feb 2016, 20:23

Secondo me il problema sta in quei

Codice: Seleziona tutto
while(!SSP1IF);

che costringono il processore ad attendere dentro il loop principale.
Mentre attende non può fare altre cose.

Credo che dovresti mettere in una variabile il punto in cui sei arrivato (lo stato).
Non ti devi fermare ad aspettare che SSP1IF diventi vero, ma lo controlli e solo se è vero esegui le azioni da fare in quello stato, e aggiorni lo stato.

In pratica dovresti strutturare la gestione dell'mcp23s17 come una macchina a stati.
Big fan of ƎlectroYou!
Avatar utente
Foto UtenteGuidoB
15,5k 7 12 13
G.Master EY
G.Master EY
 
Messaggi: 2355
Iscritto il: 3 mar 2011, 16:48
Località: Madrid

2
voti

[3] Re: Problema interrupt

Messaggioda Foto UtenteWALTERmwp » 15 feb 2016, 0:24

Ciao Foto Utentespivo, non so quanto tu possa ritenere affidabile la diagnostica del lampone, forse lo è e allora la consideriamo tale.

L'I/O expander presumo sia anch'esso collegato via SPI però dei registri interessati (per MSSP1) non si vede alcuna impostazione; mi pare non venga utilizzato l'irq, altrimenti ci sarebbe qualcosa nella relativa routine.
Non si vedono i contenuti delle prime funzioni di inizializzazione e non si vedono le dichiarazioni delle variabili, non vorrei che un array pestasse i "piedi" all'altro.
Insomma, forse mancano un po di informazioni.

Con un po di fantasia, per essere propositivo, provo ad azzardare una ipotesi: se il fault di comunicazione da parte del raspy è basato anche sul contenuto del messaggio, funzione dell'aggiornamento del contenuto dei dati ( ... SistemazioneDati(); ), allora è più che probabile che tu ti possa trovare con una valanga di errori.
E qui la soluzione sarebbe quella indicata da Foto UtenteGuidoB.

Saluti
W - U.H.F.
Avatar utente
Foto UtenteWALTERmwp
23,2k 4 8 13
G.Master EY
G.Master EY
 
Messaggi: 6833
Iscritto il: 17 lug 2010, 18:42
Località: le 4 del mattino

0
voti

[4] Re: Problema interrupt su linea SPI con pic18f46k22

Messaggioda Foto Utentespivo » 15 feb 2016, 22:33

Ciao e grazie a tutti,
Aveva ragione Foto UtenteGuidoB il problema doveva essere nei while, ora ho sostituito il codice che leggeva mcp23s17 con questo:
Codice: Seleziona tutto
    if (passo == 0) {
    // Rilevamento MCP23S17 1
    MCPD_1=0; //Indica allo slave che i dati in arrivo
        SSP1BUF=0b01000001; //indirizzo + read
        passo = 1;
    }
    if (passo == 1 && SSP1IF==1) {  //while(!SSP1IF);
        ch_canc=SSP1BUF;
        SSP1IF=0;
        passo = 2;
    }
    if (passo == 2){
        SSP1BUF=0x12; //Invio GPIOA
        passo = 3;
    }
    if (passo == 3 && SSP1IF==1) {  //while(!SSP1IF);
        ch_canc=SSP1BUF;
        SSP1IF=0;
        passo = 4;
    }
    if (passo == 4){
        SSP1BUF=0x00;
        passo = 5;
    }
    if (passo == 5 && SSP1IF==1) {   //while(!SSP1IF);
        ch_out[3]&=SSP1BUF;
        SSP1IF=0;
        passo = 6;
    }
    if (passo == 6) {
    MCPD_1=1; //Fine comunicazione
    MCPD_1=0; //Inizio comunicazione
        SSP1BUF=0b01000001; //indirizzo + read
        passo = 7;
    }
    if (passo == 7 && SSP1IF==1) {  //while(!SSP1IF);
        ch_canc=SSP1BUF;
        SSP1IF=0;
        passo = 8;
    }
    if (passo == 8) {
        SSP1BUF=0x13; //Invio GPIOB
        passo = 9;
    }
    if (passo == 9 && SSP1IF==1) {  //while(!SSP1IF);
        ch_canc=SSP1BUF;
        SSP1IF=0;
        passo = 10;
    }
    if (passo == 10) {
        SSP1BUF=0x00;
        passo = 11;
    }
    if (passo == 11 && SSP1IF==1) {//while(!SSP1IF);
        ch_out[4]&=SSP1BUF;
        SSP1IF=0;
        passo = 12;
    }
    if (passo == 12) {
    MCPD_1=1; //Fine comunicazione
    passo = 0;
    }

ora la comunicazione spi con raspberry funziona benissimo ma non riesco più a leggere il mcp23S17 #-o

P.S.
io credevo che gli interrupt interrompessero il programma indipendentemente da cosa stesse eseguendo, in teoria anche nel main c'è un ciclo infinito che comunque viene interrotto.

Grazie ancora a tutti Ciao Ivo
Avatar utente
Foto Utentespivo
375 1 12
Frequentatore
Frequentatore
 
Messaggi: 179
Iscritto il: 19 dic 2012, 21:29

0
voti

[5] Re: Problema interrupt su linea SPI con pic18f46k22

Messaggioda Foto UtenteWALTERmwp » 15 feb 2016, 22:39

spivo ha scritto:(...) non riesco più a leggere il mcp23S17 #-o (...)
e certo.
Guarda bene cosa hai scritto ...
Se, per esempio, passo vale 1 e la flag SSP1IF ti fa entrare nello "if" relativo, cosa fai, che valori imposti ?
e appena esci da quello "if" cosa succede ?

Saluti

p.s.
no, ho riportato una considerazione sbagliata, ma la lascio lì, ci "guardo" meglio ...
W - U.H.F.
Avatar utente
Foto UtenteWALTERmwp
23,2k 4 8 13
G.Master EY
G.Master EY
 
Messaggi: 6833
Iscritto il: 17 lug 2010, 18:42
Località: le 4 del mattino

0
voti

[6] Re: Problema interrupt su linea SPI con pic18f46k22

Messaggioda Foto Utentespivo » 15 feb 2016, 22:48

in teoria se passo == 1 e SSP1IF == 1 (vorrebbe dire che è arrivato il dato la da leggere) allora leggo il dato assegnandolo alla variabile ch_canc poi resetto il flag SSP1IF e avanzo di un passo che diventa 2. Quando esco se passo == 2 allora invio un altro dato e avanzo di un passo ....
:( perche non funzia?
Avatar utente
Foto Utentespivo
375 1 12
Frequentatore
Frequentatore
 
Messaggi: 179
Iscritto il: 19 dic 2012, 21:29

0
voti

[7] Re: Problema interrupt su linea SPI con pic18f46k22

Messaggioda Foto UtenteWALTERmwp » 15 feb 2016, 22:50

Ho messo il p.s.

Saluti
W - U.H.F.
Avatar utente
Foto UtenteWALTERmwp
23,2k 4 8 13
G.Master EY
G.Master EY
 
Messaggi: 6833
Iscritto il: 17 lug 2010, 18:42
Località: le 4 del mattino

0
voti

[8] Re: Problema interrupt su linea SPI con pic18f46k22

Messaggioda Foto Utentespivo » 15 feb 2016, 22:52

Scusa non avevo letto tutto
Grazie mille Ciao Ivo
Avatar utente
Foto Utentespivo
375 1 12
Frequentatore
Frequentatore
 
Messaggi: 179
Iscritto il: 19 dic 2012, 21:29

0
voti

[9] Re: Problema interrupt su linea SPI con pic18f46k22

Messaggioda Foto UtenteWALTERmwp » 16 feb 2016, 12:15

Questo loop
Codice: Seleziona tutto
for (i=0;i<2; i++) __delay_ms(1);
            LEDrosso = ~LEDrosso;
nel codice del Post [4], lo hai conservato e nella medesima posizione del codice del Post [1] ?

Saluti
W - U.H.F.
Avatar utente
Foto UtenteWALTERmwp
23,2k 4 8 13
G.Master EY
G.Master EY
 
Messaggi: 6833
Iscritto il: 17 lug 2010, 18:42
Località: le 4 del mattino

0
voti

[10] Re: Problema interrupt su linea SPI con pic18f46k22

Messaggioda Foto Utentespivo » 17 feb 2016, 22:29

Scusate il ritardo, ma purtroppo non è un bel periodo.

Ho controllato meglio il codice postato nel post[4] ed è corretto, il problema è che ci sono altre connessioni spi nelle funzioni tipo SistemazioneDati(); ed altre.
Quindi per correggere l'errore devo riscrivere tutto il codice a "passi" un bel lavoraccio.
Grazie a tutti, Ciao Ivo. O_/
Avatar utente
Foto Utentespivo
375 1 12
Frequentatore
Frequentatore
 
Messaggi: 179
Iscritto il: 19 dic 2012, 21:29

Prossimo

Torna a Firmware e programmazione

Chi c’è in linea

Visitano il forum: Nessuno e 3 ospiti