Cos'è ElectroYou | Login Iscriviti

ElectroYou - la comunità dei professionisti del mondo elettrico

Interrupt timer0 su pic12f675

Raccolta di codici sorgenti

Moderatore: Foto UtentePaolino

0
voti

[51] Re: Interrupt timer0 su pic12f675

Messaggioda Foto Utentesorecaro » 27 set 2015, 20:57

Buonasera, dopo aver "risolto" il problema del conteggio ora ne ho un altro. Con questo codice
Codice: Seleziona tutto
unsigned bit  stato; aumenta; diminuisce; stato_1; stato_2;
unsigned int zero_crossing; impulso_di_zero;  incremento;

void interrupt (void){      //interrupt per rilevamento zero_crossing
if (INTCON.GPIF){                                                        //8

    if((gpio.f3==0)&&(stato==1)) //se c'e' un fronte di discesa sul gpio.f3
    {
       impulso_di_zero++;       //incrementa impulso_di_zero
      INTCON.T0IE=1;            //abilita tmr0 con valore 255
       tmr0=206;
       stato=0;                 //resetta flag fronte discesa

     }
if((gpio.f3==1)&&(stato==0))   //se c'è stato un fronte di salita sul gpio.f3
    {
      impulso_di_zero++;       //incrementa impulso_di_zero
      INTCON.T0IE=1;           //abilita tmr0 con valore 255
      tmr0=206;
      stato=1;                  //resetta flag fronte salita

         }

if((impulso_di_zero>10)&& ( aumenta==1)) //se ci sono stati più di
{                                                  //10 passaggi per lo zero
  incremento++;                                    //ed il flag aumenta è 1
  impulso_di_zero=0;                               //aggiungi 1 a incremento
  }                                                //reset impulso_di_zero
    if( (impulso_di_zero>10) && (diminuisce==1))
  {                                              //come sopra ma per diminuire
  incremento--;                                  //
  impulso_di_zero=0;
  }

  if(incremento>=90)     //se incrementa maggiore 90 imposta flag per diminuire
  {
  aumenta=0;
  diminuisce=1;
  }

  if(incremento<10)   //se incrementa minore 10 imposta flag per aumentare
  {
  aumenta=1;
  diminuisce=0;
  }


  INTCON.GPIF=0;        //reset interrupt per porta gpio.f3
                 }




    if(INTCON.T0IF)    {      //se il timer0 ha ragguinto l'owerflow
     zero_crossing++;         //aumenta zero_crossin
     tmr0=206;                //carica il timer0 con 206 per avere un altro
                              //owerflow dopo 100us
     intcon.t0if=0;           //rese flag interrupt tmr0

    if((zero_crossing>incremento)&&(zero_crossing>=10))  //condizione per aumentare e diminuire la  gpio.f4
                                 //luminosità della lampada
     {
     gpio.f4=0;                  //innesco triac per 2us
     delay_us(2);
     gpio.f4=1;
     stato_2=1;


     }

     if((zero_crossing>=91-incremento)&&(zero_crossing>=10))  //condizione per aumentare e diminuire la gpio.f5
                                 //luminosità della lampada
     {
     gpio.f5=0;                  //innesco triac per 2us
     delay_us(2);
     gpio.f5=1;
      stato_1=1;

     }

     if((stato_1==1) && (stato_2==1))     //routine per reset interrupt tmr0
     {
       stato_1=0;
       stato_2=0;

       zero_crossing=0;
     intcon.t0if=0;
       intcon.t0ie=0;

      }


      }

      }

void main() {
impulso_di_zero=0;
   stato=0;                          //inizializza variabile
   zero_crossing=0;
   incremento=0;
   aumenta=0;
   diminuisce=0;
   stato_1=0;
   stato_2=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
   OPTION_REG=0b11000000;              //abilita presaler 1:2
   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)             //Eseguo un ciclo //finito
       {
}
     }

ho l'effetto voluto, mentre una lampada aumenta l'altra diminuisci. Il codice funziona perfettamente.
Ora vorrei implementare tramite l'ingresso analogico del PIC (ingresso ANO)un ritardo che mi permetta di impostare il tempo di aumento/decremento.
Ho impostato il codice in questo modo
Codice: Seleziona tutto
unsigned bit  stato; aumenta; diminuisce; stato_1; stato_2;
unsigned int zero_crossing; impulso_di_zero;  incremento;
unsigned int valore;


unsigned int adc(){
unsigned int pot;
unsigned int valore1;

pot=ADC_Read(0);

valore1=pot/100;

return valore1;
}





void interrupt (void){      //interrupt per rilevamento zero_crossing
if (INTCON.GPIF){                                                        //8

    if((gpio.f3==0)&&(stato==1)) //se c'e' un fornte di discesa sul gpio.f3
    {
       impulso_di_zero++;       //incrementa impulso_di_zero
      INTCON.T0IE=1;            //abilita tmr0 con valore 255
       tmr0=206;
       stato=0;                 //resetta flag fronte discesa

     }
if((gpio.f3==1)&&(stato==0))   //se c'è stato un fornte di salita sul gpio.f3
    {
      impulso_di_zero++;       //incrementa impulso_di_zero
      INTCON.T0IE=1;           //abilita tmr0 con valore 255
      tmr0=206;
      stato=1;                  //resetta flag fronte salita

         }

if((impulso_di_zero>valore)&& ( aumenta==1))    //se ci sono stati più di
{                                                  //10 passaggi per lo zero
  incremento++;                                    //ed il flag aumenta è 1
  impulso_di_zero=0;                               //aggiungi 1 a incremento
  }                                                //reset impulso_di_zero
    if( (impulso_di_zero>valore) && (diminuisce==1))
  {                                              //come sopra ma per diminuire
  incremento--;                                  //
  impulso_di_zero=0;
  }

  if(incremento>=98)     //se incremnta maggiore 75 imposta flag per diminuire
  {
  aumenta=0;
  diminuisce=1;
  }

  if(incremento<10)   //se incremnta minore 1 imposta flag per aumentare
  {
  aumenta=1;
  diminuisce=0;
  }


  INTCON.GPIF=0;        //reset interrupt per porta gpio.f3
                 }




    if(INTCON.T0IF)    {      //se il timer0 ha ragguinto l'owerflow
     zero_crossing++;         //aumenta zero_crossin
     tmr0=206;                //carica il timer0 con 206 per avere un altro
                              //owerflow dopo 100us
     intcon.t0if=0;           //rese flag interrupt tmr0

    if((zero_crossing>incremento)&&(zero_crossing>=valore))  //condizione per aumentare e diminuire la  gpio.f4
                                 //luminosità della lampada
     {
     gpio.f4=0;                  //innesco triac per 2us
     delay_us(2);
     gpio.f4=1;
     stato_2=1;


     }

     if((zero_crossing>=90-incremento)&&(zero_crossing>=valore))  //condizione per aumentare e diminuire la gpio.f5
                                 //luminosità della lampada
     {
     gpio.f5=0;                  //innesco triac per 1us
     delay_us(2);
     gpio.f5=1;
      stato_1=1;

     }

     if((stato_1==1) && (stato_2==1))     //routine per reset interrupt tmr0
     {
       stato_1=0;
       stato_2=0;

       zero_crossing=0;
     intcon.t0if=0;
       intcon.t0ie=0;

      }


      }

      }

void main() {
impulso_di_zero=0;
   stato=0;                          //inizializza variabile
   zero_crossing=0;
   incremento=0;
   aumenta=0;
   diminuisce=0;
   stato_1=0;
   stato_2=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
   OPTION_REG=0b11000000;              //abilita presaler 1:2
   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)             //Eseguo un ciclo //finito
       {
         if(incremento<10){     //se la variabile incremento è minore di 10 leggi copia il valore dell'ingresso ANO sulla varibiale valore
         
            valore=adc();
         }
         
}
     }
Avatar utente
Foto Utentesorecaro
36 3 7
Frequentatore
Frequentatore
 
Messaggi: 233
Iscritto il: 26 feb 2013, 19:30

0
voti

[52] Re: Interrupt timer0 su pic12f675

Messaggioda Foto Utentesorecaro » 27 set 2015, 21:20

Buonasera, dopo aver "risolto" il problema del conteggio ora ne ho un altro. Con questo codice
Codice: Seleziona tutto
unsigned bit  stato; aumenta; diminuisce; stato_1; stato_2;
unsigned int zero_crossing; impulso_di_zero;  incremento;

void interrupt (void){      //interrupt per rilevamento zero_crossing
if (INTCON.GPIF){                                                        //8

    if((gpio.f3==0)&&(stato==1)) //se c'e' un fronte di discesa sul gpio.f3
    {
       impulso_di_zero++;       //incrementa impulso_di_zero
      INTCON.T0IE=1;            //abilita tmr0 con valore 255
       tmr0=206;
       stato=0;                 //resetta flag fronte discesa

     }
if((gpio.f3==1)&&(stato==0))   //se c'è stato un fronte di salita sul gpio.f3
    {
      impulso_di_zero++;       //incrementa impulso_di_zero
      INTCON.T0IE=1;           //abilita tmr0 con valore 255
      tmr0=206;
      stato=1;                  //resetta flag fronte salita

         }

if((impulso_di_zero>10)&& ( aumenta==1)) //se ci sono stati più di
{                                                  //10 passaggi per lo zero
  incremento++;                                    //ed il flag aumenta è 1
  impulso_di_zero=0;                               //aggiungi 1 a incremento
  }                                                //reset impulso_di_zero
    if( (impulso_di_zero>10) && (diminuisce==1))
  {                                              //come sopra ma per diminuire
  incremento--;                                  //
  impulso_di_zero=0;
  }

  if(incremento>=90)     //se incrementa maggiore 90 imposta flag per diminuire
  {
  aumenta=0;
  diminuisce=1;
  }

  if(incremento<10)   //se incrementa minore 10 imposta flag per aumentare
  {
  aumenta=1;
  diminuisce=0;
  }


  INTCON.GPIF=0;        //reset interrupt per porta gpio.f3
                 }




    if(INTCON.T0IF)    {      //se il timer0 ha ragguinto l'owerflow
     zero_crossing++;         //aumenta zero_crossin
     tmr0=206;                //carica il timer0 con 206 per avere un altro
                              //owerflow dopo 100us
     intcon.t0if=0;           //rese flag interrupt tmr0

    if((zero_crossing>incremento)&&(zero_crossing>=10))  //condizione per aumentare e diminuire la  gpio.f4
                                 //luminosità della lampada
     {
     gpio.f4=0;                  //innesco triac per 2us
     delay_us(2);
     gpio.f4=1;
     stato_2=1;


     }

     if((zero_crossing>=91-incremento)&&(zero_crossing>=10))  //condizione per aumentare e diminuire la gpio.f5
                                 //luminosità della lampada
     {
     gpio.f5=0;                  //innesco triac per 2us
     delay_us(2);
     gpio.f5=1;
      stato_1=1;

     }

     if((stato_1==1) && (stato_2==1))     //routine per reset interrupt tmr0
     {
       stato_1=0;
       stato_2=0;

       zero_crossing=0;
     intcon.t0if=0;
       intcon.t0ie=0;

      }


      }

      }

void main() {
impulso_di_zero=0;
   stato=0;                          //inizializza variabile
   zero_crossing=0;
   incremento=0;
   aumenta=0;
   diminuisce=0;
   stato_1=0;
   stato_2=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
   OPTION_REG=0b11000000;              //abilita presaler 1:2
   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)             //Eseguo un ciclo //finito
       {
}
     }

ho l'effetto voluto, mentre una lampada aumenta l'altra diminuisci. Il codice funziona perfettamente.
Ora vorrei implementare tramite l'ingresso analogico del PIC (ingresso ANO)un ritardo che mi permetta di impostare il tempo di aumento/decremento.
Ho impostato il codice in questo modo ( perdonatemi se posto il codice in modo "NON CORRETTO" ma ho evidenziato in rosso le modifiche)



unsigned bit stato; aumenta; diminuisce; stato_1; stato_2;
unsigned int zero_crossing; impulso_di_zero; incremento;
unsigned int valore;

unsigned int adc(){ //funzione per leggere il valore dell'ingresso AN0
unsigned int pot;
unsigned int valore1;

pot=ADC_Read(0);

valore1=pot/100;

return valore1;
}

void interrupt (void){ //interrupt per rilevamento zero_crossing
if (INTCON.GPIF){ //8

if((gpio.f3==0)&&(stato==1)) //se c'e' un fornte di discesa sul gpio.f3
{
impulso_di_zero++; //incrementa impulso_di_zero
INTCON.T0IE=1; //abilita tmr0 con valore 255
tmr0=206;
stato=0; //resetta flag fronte discesa

}
if((gpio.f3==1)&&(stato==0)) //se c'è stato un fornte di salita sul gpio.f3
{
impulso_di_zero++; //incrementa impulso_di_zero
INTCON.T0IE=1; //abilita tmr0 con valore 255
tmr0=206;
stato=1; //resetta flag fronte salita

}

if((impulso_di_zero>valore)&& ( aumenta==1)) //se ci sono stati più di
{ //10 passaggi per lo zero
incremento++; //ed il flag aumenta è 1
impulso_di_zero=0; //aggiungi 1 a incremento
} //reset impulso_di_zero
if( (impulso_di_zero>valore) && (diminuisce==1))
{ //come sopra ma per diminuire
incremento--; //
impulso_di_zero=0;
}

if(incremento>=91) //se incrementa maggiore 91 imposta flag per diminuire
{
aumenta=0;
diminuisce=1;
}

if(incremento<10) //se incrementa minore 10 imposta flag per aumentare
{
aumenta=1;
diminuisce=0;
}
INTCON.GPIF=0; //reset interrupt per porta gpio.f3
}

if(INTCON.T0IF) { //se il timer0 ha ragguinto l'owerflow
zero_crossing++; //aumenta zero_crossin
tmr0=206; //carica il timer0 con 206 per avere un altro
//owerflow dopo 100us
intcon.t0if=0; //rese flag interrupt tmr0

if((zero_crossing>incremento)&&(zero_crossing>=valore)) //condizione per aumentare e diminuire la gpio.f4
//luminosità della lampada
{
gpio.f4=0; //innesco triac per 2us
delay_us(2);
gpio.f4=1;
stato_2=1;
}
if((zero_crossing>=90-incremento)&&(zero_crossing>=valore)) //condizione per aumentare e diminuire la gpio.f5
//luminosità della lampada
{
gpio.f5=0; //innesco triac per 2us
delay_us(2);
gpio.f5=1;
stato_1=1;
}
if((stato_1==1) && (stato_2==1)) //routine per reset interrupt tmr0
{
stato_1=0;
stato_2=0;
zero_crossing=0;
intcon.t0if=0;
intcon.t0ie=0;
}
}
}

void main() {
impulso_di_zero=0;
stato=0; //inizializza variabile
zero_crossing=0;
incremento=0;
aumenta=0;
diminuisce=0;
stato_1=0;
stato_2=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
OPTION_REG=0b11000000; //abilita presaler 1:2
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) //Eseguo un ciclo //finito
{
if(incremento<10){ //se la variabile incremento è minore di 10 copia il valore dell'ingresso ANO sulla variabile valore

valore=adc();
}


}
}
ma purtroppo aggiungendo nel main il controllo della variabile incremento per decidere se leggere il valore dell'ingresso AN0 il tempo di accensione/spegnimento delle due lampade non è più lineare. Quello che si verifica cerco di descriverlo nel miglior modo possibile:
1) all'accensione dell'interruttore generale (220VAC) ho un flash sulle due lampade
2)piccolo tempo di pausa
3)accensione completa lampada 1
4)mentre la lampada 1 comincia a diminuire la lampada 2 aumenta
5)arrivati circa all 80% delle due "rampe" si spengono entrambe
6)le lampade lampeggiando entrambe
7) dopo il lampeggio il sistema si stabilizza
8) lampada 1 aumenta e lampada 2 diminuisce
8) ritorna al punto 5

Dopo varie prove credo che il problema sia dovuto al ritardo che crea la conversione del valore analogico.
La mia domanda era:
se la conversione dell'ingresso analogico la eseguo tramite interrupt il problema rimane?? Troppo codice nella routine di interrupt può causare problemi?? Premetto che l'unica cosa da aggiungere è questa (lettura valore AN0) e poi il codice è finito
Avatar utente
Foto Utentesorecaro
36 3 7
Frequentatore
Frequentatore
 
Messaggi: 233
Iscritto il: 26 feb 2013, 19:30

1
voti

[53] Re: Interrupt timer0 su pic12f675

Messaggioda Foto Utentesorecaro » 30 set 2015, 14:43

Buongiorno, dopo varie prove ho risolto il problema, dovevo impostare meglio il conteggio delle variabili ora il codice è perfetto. :D Volevo ringraziarvi per l'aiuto ed i consigli che mi avete dato, ma soprattutto un grazie a Foto UtenteWALTERmwp e Foto UtentePaolino
Avatar utente
Foto Utentesorecaro
36 3 7
Frequentatore
Frequentatore
 
Messaggi: 233
Iscritto il: 26 feb 2013, 19:30

0
voti

[54] Re: Interrupt timer0 su pic12f675

Messaggioda Foto UtentePaolino » 30 set 2015, 14:47

Sono contento. Io ho fatto un poco, incasinato come al solito, alle prese con un fw che non ne vuole sapere di fare quello che gli chiedo.
Mannaggia. ||O ||O

Bravo, comunque. :D :D :ok: :ok:

Ciao.

Paolo.
"Houston, Tranquillity Base here. The Eagle has landed." - Neil A.Armstrong

-------------------------------------------------------------

PIC Experience - http://www.picexperience.it
Avatar utente
Foto UtentePaolino
32,0k 8 12 13
G.Master EY
G.Master EY
 
Messaggi: 4184
Iscritto il: 20 gen 2006, 11:42
Località: Vigevano (PV)

0
voti

[55] Re: Interrupt timer0 su pic12f675

Messaggioda Foto UtenteWALTERmwp » 30 set 2015, 14:49

sorecaro ha scritto:un grazie a WALTERmwp e Foto UtentePaolino
di nulla figurati, comunque, a volte, può essere di aiuto anche lasciare un pochino sedimentare il thread ...
Buona prosecuzione.

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

Precedente

Torna a Firmware e programmazione

Chi c’è in linea

Visitano il forum: Nessuno e 1 ospite