Cos'è ElectroYou | Login Iscriviti

ElectroYou - la comunità dei professionisti del mondo elettrico

Come risolvere una lunga cascata di IF

Raccolta di codici sorgenti

Moderatore: Foto UtentePaolino

0
voti

[21] Re: Come risolvere una lunga cascata di IF

Messaggioda Foto UtenteGioArca67 » 23 ott 2021, 14:13

EcoTan ha scritto:Ho una routine ISR fatta più o meno così:

[....]

In questo modo funziona ma sicuramente si può fare meglio, però io non sono capace.


Chiede come fare meglio. Domanda generica.

Dal codice postato sembra necessario solo
Codice: Seleziona tutto
stato++;
intNum++;
IFS1bits.MI2C1IF = 0;
Avatar utente
Foto UtenteGioArca67
4.585 4 6 9
Master EY
Master EY
 
Messaggi: 4595
Iscritto il: 12 mar 2021, 9:36

0
voti

[22] Re: Come risolvere una lunga cascata di IF

Messaggioda Foto UtentePietroBaima » 23 ott 2021, 14:22

No, leggi il titolo del thread.
Generatore codice per articoli:
nomi
Sul forum:
[pigreco]=π
[ohm]=Ω
[quadrato]=²
[cubo]=³
Avatar utente
Foto UtentePietroBaima
90,7k 7 12 13
G.Master EY
G.Master EY
 
Messaggi: 12207
Iscritto il: 12 ago 2012, 1:20
Località: Londra

0
voti

[23] Re: Come risolvere una lunga cascata di IF

Messaggioda Foto UtenteEcoTan » 23 ott 2021, 18:30

Grazzie! Funziona:

Codice: Seleziona tutto
void __attribute__((no_auto_psv)) _ISRFAST _MI2C1Interrupt(void) {//ISR I2C master 
    switch(stato) {
        case 0:     //inizio
//if (I2C1STATbits.P==1)stato++; else goto res;//se ozioso (idle) fa start altrimenti resetta
I2C1CONbits.SEN=1;    //start bit
IFS1bits.MI2C1IF = 0;  stato++; break; 
        case 1:     //dopo start
//if (I2C1STATbits.S==1)stato++; else goto res;  //se fatto start altrimenti resetta
I2C1TRN=0b11010000;  //slave address GY521 x68 con bit trasmissione=0 
IFS1bits.MI2C1IF = 0; stato++; break;   
        case 2:     //se ha scritto slave address
//if (I2C1STATbits.ACKSTAT == 0)stato++; else goto res;//se ACK scrive sub address registro slave
  I2C1TRN=0b00111101; //x3D indirizzo registro accelerometro Y
IFS1bits.MI2C1IF = 0; stato++; break; 
        case 3:     //se ha scritto indirizzo registro slave
//if (I2C1STATbits.ACKSTAT == 0)stato++; else goto res;//se ACK ripete start
I2C1CONbits.RSEN=1;  //repeated start
IFS1bits.MI2C1IF = 0; stato++; break; 
        case 4:     //dopo start
//if (I2C1STATbits.S==1)stato++; else goto res;  //se fatto start altrimenti resetta
I2C1TRN=0b11010001;  //slave address GY521 x68 con bit ricezione=1 
IFS1bits.MI2C1IF = 0; stato++; break; 
        case 5:     //se era indirizzo slave lettura
//if (I2C1STATbits.ACKSTAT == 0)stato++; else goto res;//se ACK
I2C1CONbits.RCEN=1;  //abilitazione lettura
IFS1bits.MI2C1IF = 0; stato++; break; 
        case 6:     //
//if (I2C1STATbits.RBF == 1)stato++; else goto res;//se letto primo byte fa ACK
hbyte=I2C1RCV;  //e memorizza lettura
I2C1CONbits.ACKDT=0;//predispone Ack da master
I2C1CONbits.ACKEN=1;//Ack
IFS1bits.MI2C1IF = 0; stato++; break; 
        case 7:     //
//if (I2C1STATbits.ACKSTAT == 0)stato++; else goto res;//se  ACK
I2C1CONbits.RCEN=1;  //abilitazione lettura
IFS1bits.MI2C1IF = 0; stato++; break; 
        case 8:     //
//if (I2C1STATbits.RBF == 1)stato++; else goto res;//se letto secondo byte fa ACK
lbyte=I2C1RCV;  //e memorizza lettura
ay=((hbyte<<8)+lbyte);//lettura asse y accelerometro
I2C1CONbits.ACKEN=1;//Ack
IFS1bits.MI2C1IF = 0; stato++; break;
        case 9:     //se era indirizzo slave lettura
//if (I2C1STATbits.ACKSTAT == 0)stato++; else goto res;//se ACK
I2C1CONbits.RCEN=1;  //abilitazione lettura
IFS1bits.MI2C1IF = 0; stato++; break; 
        case 10:     //
//if (I2C1STATbits.RBF == 1)stato++; else goto res;//se letto primo byte fa ACK
hbyte=I2C1RCV;  //e memorizza lettura
I2C1CONbits.ACKDT=0;//predispone Ack da master
I2C1CONbits.ACKEN=1;//Ack
IFS1bits.MI2C1IF = 0; stato++; break; 
        case 11:     //
//if (I2C1STATbits.ACKSTAT == 0)stato++; else goto res;//se  ACK
I2C1CONbits.RCEN=1;  //abilitazione lettura
IFS1bits.MI2C1IF = 0; stato++; break; 
        case 12:     //
//if (I2C1STATbits.RBF == 1)stato++; else goto res;//se letto secondo byte fa ACK
lbyte=I2C1RCV;  //e memorizza lettura
//az=((hbyte<<8)+lbyte);//lettura asse z accelerometro
I2C1CONbits.ACKEN=1;//Ack
IFS1bits.MI2C1IF = 0; stato++; break;
        case 13:     //se era indirizzo slave lettura
//if (I2C1STATbits.ACKSTAT == 0)stato++; else goto res;//se ACK
I2C1CONbits.RCEN=1;  //abilitazione lettura
IFS1bits.MI2C1IF = 0; stato++; break; 
        case 14:     //
//if (I2C1STATbits.RBF == 1)stato++; else goto res;//se letto primo byte fa ACK
hbyte=I2C1RCV;  //e memorizza lettura
I2C1CONbits.ACKDT=0;//predispone Ack da master
I2C1CONbits.ACKEN=1;//Ack
IFS1bits.MI2C1IF = 0; stato++; break; 
        case 15:     //
//if (I2C1STATbits.ACKSTAT == 0)stato++; else goto res;//se  ACK
I2C1CONbits.RCEN=1;  //abilitazione lettura
IFS1bits.MI2C1IF = 0; stato++; break; 
        case 16:     //
//if (I2C1STATbits.RBF == 1)stato++; else goto res;//se letto secondo byte fa ACK
lbyte=I2C1RCV;  //e memorizza lettura
//temp=((hbyte<<8)+lbyte);//lettura temperatura
I2C1CONbits.ACKEN=1;//Ack
IFS1bits.MI2C1IF = 0; stato++; break;
        case 17:     //se era secondo byte
//if (I2C1STATbits.ACKSTAT == 0)stato++; else goto res;//se ACK
I2C1CONbits.RCEN=1;  //abilitazione lettura altro asse
IFS1bits.MI2C1IF = 0; stato++; break; 
        case 18:     //
//if (I2C1STATbits.RBF == 1)stato++; else goto res;//se letto primo byte fa ACK
hbyte=I2C1RCV;  //e memorizza lettura
I2C1CONbits.ACKEN=1;//Ack
IFS1bits.MI2C1IF = 0; stato++; break; 
        case 19:     //
//if (I2C1STATbits.ACKSTAT == 0)stato++; else goto res;//se  ACK
I2C1CONbits.RCEN=1;  //abilitazione lettura
IFS1bits.MI2C1IF = 0; stato++; break; 
        case 20:     //
//if (I2C1STATbits.RBF == 1)stato++; else goto res;//se letto secondo byte manda NACK
lbyte=I2C1RCV;  //e memorizza lettura
I2C1CONbits.ACKDT=1;//predispone NAck da master
gx=((hbyte<<8)+lbyte);        //lettura asse x giroscopio
I2C1CONbits.ACKEN=1;//NAck
IFS1bits.MI2C1IF = 0; stato++; break; 
        case 21:     //dopo Nack mandato da master
I2C1CONbits.PEN=1;//Stop
IFS1bits.MI2C1IF = 0; stato=0; break; 

        case 81:     //configurazione dopo start
//if (I2C1STATbits.S==1)stato++; else goto res;  //se fatto start altrimenti resetta
  I2C1TRN=0b11010000;  //slave address GY521 x68 con bit trasmissione=0
IFS1bits.MI2C1IF = 0; stato++; break; 
        case 82:     //se ha scritto slave address
//if (I2C1STATbits.ACKSTAT == 0)stato++; else goto res; //se ACK scrive indirizzo registro slave
  I2C1TRN=0b01101011; //sub address registro configurazione power management x6B
IFS1bits.MI2C1IF = 0; stato++; break; 
        case 83:     //se ha scritto sub address registro slave
//if (I2C1STATbits.ACKSTAT == 0)stato++; else goto res; //se ACK manda configurazione
  I2C1TRN=0b00000001; //LSB=clock da accelerometro x
IFS1bits.MI2C1IF = 0; stato++; break;
        case 84:     //se ha mandato configurazione
//if (I2C1STATbits.ACKSTAT == 0)stato++; else goto res; //se ACK stop poi configura
I2C1CONbits.PEN=1;//Stop
IFS1bits.MI2C1IF = 0; stato++; break;
        case 85:     //prosegue configurazione
//if (I2C1STATbits.P==1)stato++; else goto res;//se era ozioso (idle) fa start altrimenti resetta
I2C1CONbits.SEN=1;    //start bit
IFS1bits.MI2C1IF = 0; stato++; break; 
        case 86:     //dopo start
//if (I2C1STATbits.S==1)stato++; else goto res;  //se fatto start altrimenti resetta
I2C1TRN=0b11010000;  //slave address GY521 x68 con bit trasmissione=0
IFS1bits.MI2C1IF = 0; stato++; break; 
        case 87:     //se ha scritto slave address
//if (I2C1STATbits.ACKSTAT == 0)stato++; else goto res; //se ACK scrive sub-address registro slave
  I2C1TRN=0b00011100; //sub address registro configurazione accelerometro x1C
IFS1bits.MI2C1IF = 0; stato++; break; 
        case 88:     //se ha scritto sub address registro slave
//if (I2C1STATbits.ACKSTAT == 0)stato++; else goto res; //se ACK manda configurazione accelerometro
I2C1TRN=0b00000000; //configurazione accelerometro, dovrebbe essere ininfluente
IFS1bits.MI2C1IF = 0; stato++; break;
        case 89:     //se ha mandato configurazione
//if (I2C1STATbits.ACKSTAT == 0)stato=0; else goto res; //se ACK fa stop
I2C1CONbits.PEN=1;//Stop
IFS1bits.MI2C1IF = 0; stato=0; break; } }


Ho abolito la label res: e tutte le relative goto che nelle intenzioni dovevano servire a resettare il colloquio in caso di errore.
Avatar utente
Foto UtenteEcoTan
7.720 4 12 13
Expert EY
Expert EY
 
Messaggi: 5426
Iscritto il: 29 gen 2014, 8:54

0
voti

[24] Re: Come risolvere una lunga cascata di IF

Messaggioda Foto UtentePietroBaima » 23 ott 2021, 18:40

Hai capito tutto... non si fa così :!:
Generatore codice per articoli:
nomi
Sul forum:
[pigreco]=π
[ohm]=Ω
[quadrato]=²
[cubo]=³
Avatar utente
Foto UtentePietroBaima
90,7k 7 12 13
G.Master EY
G.Master EY
 
Messaggi: 12207
Iscritto il: 12 ago 2012, 1:20
Località: Londra

0
voti

[25] Re: Come risolvere una lunga cascata di IF

Messaggioda Foto UtenteEcoTan » 23 ott 2021, 19:01

Per l'uso del puntatore sto ancora studiando, forse ciascun caso prenderà la forma di una funzione?
Avatar utente
Foto UtenteEcoTan
7.720 4 12 13
Expert EY
Expert EY
 
Messaggi: 5426
Iscritto il: 29 gen 2014, 8:54

0
voti

[26] Re: Come risolvere una lunga cascata di IF

Messaggioda Foto Utentelucaking » 23 ott 2021, 19:03

Io evito di dire castronerie, ma l' uso dell' array di puntatori a funzione mi interessa, e visto che non ho ancora capito come farlo in questo caso specifico, resto in ascolto.
Avatar utente
Foto Utentelucaking
1.651 4 5 8
Expert
Expert
 
Messaggi: 1445
Iscritto il: 29 mag 2015, 14:28

0
voti

[27] Re: Come risolvere una lunga cascata di IF

Messaggioda Foto UtentePietroBaima » 23 ott 2021, 19:30

Appena posso scrivo un esempio, però ragazzi, basta guardare il video per capire come fare.
Comunque adesso non ho tempo, appena posso lo faccio.
Generatore codice per articoli:
nomi
Sul forum:
[pigreco]=π
[ohm]=Ω
[quadrato]=²
[cubo]=³
Avatar utente
Foto UtentePietroBaima
90,7k 7 12 13
G.Master EY
G.Master EY
 
Messaggi: 12207
Iscritto il: 12 ago 2012, 1:20
Località: Londra

0
voti

[28] Re: Come risolvere una lunga cascata di IF

Messaggioda Foto UtentePietroBaima » 23 ott 2021, 19:31

EcoTan ha scritto:Per l'uso del puntatore sto ancora studiando, forse ciascun caso prenderà la forma di una funzione?

Si
Generatore codice per articoli:
nomi
Sul forum:
[pigreco]=π
[ohm]=Ω
[quadrato]=²
[cubo]=³
Avatar utente
Foto UtentePietroBaima
90,7k 7 12 13
G.Master EY
G.Master EY
 
Messaggi: 12207
Iscritto il: 12 ago 2012, 1:20
Località: Londra

5
voti

[29] Re: Come risolvere una lunga cascata di IF

Messaggioda Foto Utentexyz » 23 ott 2021, 22:16

lucaking ha scritto:si può fare qualcosa di piu smart?

Io quando devo implementare in un microcontrollore una FSM abbastanza complessa uso questo programma:

http://www.colm.net/open-source/ragel/

Il codice che genera è parecchio ottimizzato ma bisogna saperlo usare. Permette di generare il grafo degli stati nel formato usato da Graphviz.
Avatar utente
Foto Utentexyz
6.864 2 4 6
G.Master EY
G.Master EY
 
Messaggi: 1778
Iscritto il: 5 dic 2009, 18:37
Località: Italy Turin

0
voti

[30] Re: Come risolvere una lunga cascata di IF

Messaggioda Foto Utentefairyvilje » 24 ott 2021, 4:06

Non l'avevo mai visto. Sembra molto ispirato a bison/flex o viceversa :D.
Probabilmente è più minimalista nel codice generato che è un bene per sistemi con poco spazio a disposizione.
"640K ought to be enough for anybody" Bill Gates (?) 1981
Qualcosa non ha funzionato...

Lo sapete che l'arroganza in informatica si misura in nanodijkstra? :D
Avatar utente
Foto Utentefairyvilje
15,0k 4 9 12
G.Master EY
G.Master EY
 
Messaggi: 3047
Iscritto il: 24 gen 2012, 19:23

PrecedenteProssimo

Torna a Firmware e programmazione

Chi c’è in linea

Visitano il forum: Nessuno e 19 ospiti