Pagina 1 di 2

Ottimizzare codice C su PIC

MessaggioInviato: 23 ott 2015, 23:14
da sorecaro
Salve a tutti. Ho scritto questo codice per pilotare 4 triac (effetti luce). Ora vorrei implementare altri "effetti" nel programma ma sono già a metà della ROM. (usata 50%). Come posso ottimizzare il codice? Il problema è che devo aggiungere altri effetti e non so come fare
Codice: Seleziona tutto
           //////LUCI 4 CH /////////////

unsigned bit zero_crossing; stato;
unsigned char  i; imp; contatore;
unsigned int tempo;
unsigned char porta;
/////////////////////////LETTURA ANALOGICA GP0/////////////////////////////////
unsigned int adc(){
   unsigned int pot;
   unsigned int valore1;
        pot=ADC_Read(0);
        valore1=pot/30;
        return valore1;

      }

                  /////////////////////////yy//''ìì////ok/////////////

void interrupt (void){
if (INTCON.GPIF){              //se c'è stato interrupt


if(i>=84+tempo*4)
{
i=60;
++contatore;
}

if((gpio.f3==1) && (stato==0)) //se gp3 è 1 e stato 0 allora
{
i++;
for(imp=0; imp<=400; imp++) {
  gpio^=porta;
  delay_us(2);
  gpio^=porta;
   }
    stato=1;
    INTCON.GPIF=0;
}

if ((gpio.f3==0) && (stato==1)) //se c'è stato un fronte di discesa
{
   for(imp=0; imp<=400; imp++){
  gpio^=porta;
  delay_us(2);
  gpio^=porta;
  }
    stato=0;
  INTCON.GPIF=0;
}
}
}

////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////



void main() {
    stato=0;                          //inizializza variabile
    i=0;
   zero_crossing=0;
   contatore=0;
   CMCON =  7;                         //Disabilita comparatore
   ADCON0 = 0b000000001;                //Aisabilita convertitore A/D
   ANSEL =  0b00000001;                //Tutte le porte in digitale tranne gp0
   TRISIO = 0b00001001;                //Tutti i pin in OUT tranne gpio3
   IOC=     0b001000;                  //imposta interrupt su pin 3
   INTCON.GPIE   =1;                   //abilita interrupt generale
   INTCON.GIE    =1;                    //abiita interrupt su porta gpio
   gpio.f1=1;                           //imposta le uscite a 1
   gpio.f2=1;
   gpio.f4=1;
   gpio.f5=1;



while(1)
       {

       unsigned int valore;



////////////////////////////    GIOCO 1   //////////////////////////////////////////////////////////////////////////////////////////////////

if(contatore<10){

if(i<=60)
{
porta=0b000000;
  valore=adc();
  tempo=valore;
  }

if ((i>=60)&&(i<66+valore))
  {
porta=0b010000;
  }
  if ((i>=66+valore) && (i<72+valore*2))
{
    porta=0b100000;
}
if ((i>=72+valore*2)&&(i<78+valore*3))
{
porta=0b000100;
}
if ((i>=78+valore*3)&&(i<84+valore*4))
{
porta=0b000010;
}
}

}
}

Re: Ottimizzare codice C su PIC

MessaggioInviato: 24 ott 2015, 1:21
da WALTERmwp
Ciao Foto Utentesorecaro, il programma è contenuto, sono poche righe ( ... in C ), quindi mi pare ci sia poco da "limare".
Se proprio proprio vuoi speculare credo tu debba considerare il disassemblato e studiartelo bene.
Se invece il compilatore già ottimizza c'è poco tu possa fare meglio di lui.
Prova ad implementare per gradi e valuta di volta in volta l'occupazione di memoria.
Lo so che è una ovvietà ma è pure ovvio che non puoi sapere a priori se saturerai la risorsa.

Saluti

Re: Ottimizzare codice C su PIC

MessaggioInviato: 24 ott 2015, 14:03
da sorecaro
Ciao Foto UtenteWALTERmwp grazie per l'aiuto. Stasera provo a scrivere il main in modo diverso e vedere se riesco ad inserire altri effetti. Ho in mente una cosa , per ora molto contorta ma penso che possa funzionare. Ti terrò aggiornato

Re: Ottimizzare codice C su PIC

MessaggioInviato: 3 nov 2015, 19:12
da grandegiove
sorecaro ha scritto:Salve a tutti. Ho scritto questo codice per pilotare 4 triac (effetti luce). Ora vorrei implementare altri "effetti" nel programma ma sono già a metà della ROM. (usata 50%). Come posso ottimizzare il codice? Il problema è che devo aggiungere altri effetti e non so come fare


Quale PIC hai usato? Hai controllato se ne esiste uno pin compatibile con più memoria? Così sì che ti potresti sbizzarrire.. :ok:

Re: Ottimizzare codice C su PIC

MessaggioInviato: 4 nov 2015, 9:48
da gb88
Cosi ad occhio puoi provare 3 ottimizzazioni:
1- nella funzione adc puoi fare tutto con una riga
2- sostituire la moltiplicazione con degli shift (es: valore valore*3 => valore<<1+valore)
3- far diventare la variabile valore globale e togliere la dichiarazione dal while 1 ed eliminare tempo che diventa valore (dato che tempo era letta solo una volta)
Codice: Seleziona tutto
           //////LUCI 4 CH /////////////

unsigned bit zero_crossing; stato;
unsigned char  i; imp; contatore;
unsigned int valore;
unsigned char porta;
/////////////////////////LETTURA ANALOGICA GP0/////////////////////////////////
unsigned int adc(){
        return ADC_Read(0)/30;
      }

                  /////////////////////////yy//''ìì////ok/////////////

void interrupt (void){
if (INTCON.GPIF){              //se c'è stato interrupt


if(i>=84+valore<<2)
{
i=60;
++contatore;
}

if((gpio.f3==1) && (stato==0)) //se gp3 è 1 e stato 0 allora
{
i++;
for(imp=0; imp<=400; imp++) {
  gpio^=porta;
  delay_us(2);
  gpio^=porta;
   }
    stato=1;
    INTCON.GPIF=0;
}

if ((gpio.f3==0) && (stato==1)) //se c'è stato un fronte di discesa
{
   for(imp=0; imp<=400; imp++){
  gpio^=porta;
  delay_us(2);
  gpio^=porta;
  }
    stato=0;
  INTCON.GPIF=0;
}
}
}

////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////



void main() {
    stato=0;                          //inizializza variabile
    i=0;
   zero_crossing=0;
   contatore=0;
   CMCON =  7;                         //Disabilita comparatore
   ADCON0 = 0b000000001;                //Aisabilita convertitore A/D
   ANSEL =  0b00000001;                //Tutte le porte in digitale tranne gp0
   TRISIO = 0b00001001;                //Tutti i pin in OUT tranne gpio3
   IOC=     0b001000;                  //imposta interrupt su pin 3
   INTCON.GPIE   =1;                   //abilita interrupt generale
   INTCON.GIE    =1;                    //abiita interrupt su porta gpio
   gpio.f1=1;                           //imposta le uscite a 1
   gpio.f2=1;
   gpio.f4=1;
   gpio.f5=1;



while(1)
       {
////////////////////////////    GIOCO 1   //////////////////////////////////////////////////////////////////////////////////////////////////

if(contatore<10){

if(i<=60)
{
porta=0b000000;
  valore=adc();
  }

if ((i>=60)&&(i<66+valore))
  {
porta=0b010000;
  }
  if ((i>=66+valore) && (i<72+valore<<1))
{
    porta=0b100000;
}
if ((i>=72+valore<<1)&&(i<78+(valore<<1+valore)))
{
porta=0b000100;
}
if ((i>=78+(valore<<1+valore)&&(i<84+valore<<2))
{
porta=0b000010;
}
}

}
}

Re: Ottimizzare codice C su PIC

MessaggioInviato: 4 nov 2015, 9:57
da sorecaro
Buongiorno, dopo varie prove ho risolto utilizzando switch al posto di if. In questo modo sono riuscito ad inserire 8 effetti luci. Appena riesco posto il codice

Re: Ottimizzare codice C su PIC

MessaggioInviato: 4 nov 2015, 10:13
da TardoFreak
E' bellissimo parlare di microcontrollori senza sapere neanche di che microcontrollore e di quale compilatore si sta parlando. :roll:

Re: Ottimizzare codice C su PIC

MessaggioInviato: 4 nov 2015, 12:31
da sorecaro
Hai ragione. Il micro é un PIC 12f675 e come compilatore uso mikroc pro

Re: Ottimizzare codice C su PIC

MessaggioInviato: 4 nov 2015, 12:36
da TardoFreak
MikroC non è un campione in termini di occupazione di memoria.
Solitamente le chiamate alle funzioni sono sempre del tipo "inline" e quindi ottimizzate per la velocità ma non per la FLASH.

Edit: E, detto fra noi, è il modo più semplice per compilare C sui PIC piccolini senza implementare uno stack virtuale.

Re: Ottimizzare codice C su PIC

MessaggioInviato: 5 nov 2015, 0:32
da AlbertoBianchi
Ciao, non sono un' esperto di PIC ma vorrei far presente un pio di cose di carattere generale che credo comunque siano applicabili anche in questo caso:

1) stiamo lavorando in C e quindi dobbiamo tener presente che all' eseguibile verranno lincate le librerie di run-time tipiche appunto del C (tradizionalmente le libc) e nello specifico quelle presenti nel compilatore che stai usando.

Questo in pratica significa che anche se scrivi poche righe di codice il linker subito aggiunge le una quota parte del codice delle librerie (aggiungerà automaticamente le routines che servono, in funzione del tipo di codice che hai scritto).
Quindi c'è uno "zocccolo duro", di codice nascosto che subito ti va ad occupare memoria flash.
La progressione di utilizzo della flash non cresce linearmente con la quantità di righe di codice che scrivi; all'inizio ci sarà appunto un occupazione di memoria sensibile, ma poi ti accorgerai che via via che aggiungi righe di codice la dimensione dell' eseguibile aumenta in proporzione molto, molto meno.

2) nei compilatori di solito ci sono una serie di opzioni per ottimizzare il codice; studia bene cosa offre in tal senso il tuo compilatore. Il codice compilato senza nessuna di queste opzioni, di solito è piuttosto ingombrante.

Tieni conto però che se utilizzi qualche tipo di debug, (non so cosa offra, in questo senso microchip per il tuo PIC) in genere conviene disabilitare le ottimizzazioni.

Io in genere non mi preoccupo di fare ottimizzazioni di codice orientate al contenimento del size, fino a quando non raggiungo circa l'80% della capienza della flash e consiglierei anche a te di procedere in questo modo.

Le poche righe di codice che hai scritto una volta compilate con le opzioni di ottimizzazione, ad occhio e croce potranno pesare qualche centinaio di bytes circa, il resto del 50% sono librerie di run-time.