Cos'è ElectroYou | Login Iscriviti

ElectroYou - la comunità dei professionisti del mondo elettrico

PIC e ricezione telecomando infrarossi

Raccolta di codici sorgenti

Moderatore: Foto UtentePaolino

0
voti

[11] Re: PIC e ricezione telecomandoinfrarossi

Messaggioda Foto UtentePaolino » 6 ott 2015, 15:44

Ma non puoi usare interrupt on change?
"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: 4186
Iscritto il: 20 gen 2006, 11:42
Località: Vigevano (PV)

0
voti

[12] Re: PIC e ricezione telecomandoinfrarossi

Messaggioda Foto UtenteIlGuru » 6 ott 2015, 15:51

Paolino ha scritto:Ma non puoi usare interrupt on change?


Quello che mi chiedevo anche io, visto che ha anche definito una interrupt service routine, ma vuole fare tutto nel main.
\Gamma\nu\tilde{\omega}\theta\i\ \sigma\epsilon\alpha\upsilon\tau\acute{o}\nu
Avatar utente
Foto UtenteIlGuru
4.134 1 10 13
Master
Master
 
Messaggi: 1372
Iscritto il: 31 lug 2015, 23:32

0
voti

[13] Re: PIC e ricezione telecomandoinfrarossi

Messaggioda Foto Utentesorecaro » 6 ott 2015, 15:53

Grazie per l'aiuto che mi state dando.
Ho modificato il codice usando l'interrupt sul gpio.f4 come da voi consigliato.
Codice: Seleziona tutto
signed short ricevo[20]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};

unsigned bit flag_discesa; flag_salita; inizio_ricezione;  alto; basso;
unsigned bit stop_tempo; leggi; stop; start;
unsigned short tempo_trascorso;
unsigned short incremento_byte;

void interrupt(void){

     if(intcon.gpif){

           if((gpio.f4==1)&&(alto==0))
              {
              gpio.f1=1;
               INTCON.T0IE=1;
              tmr0=0;
              stop_tempo=0;
              tempo_trascorso=0;
              alto=1;
              start=0;
              intcon.gpif=0;
              }
              if((gpio.f4==0)&&(alto==1))
              {
              gpio.f1=0;
              tempo_trascorso=tmr0;
              INTCON.T0IE=0;
              stop_tempo=1;
              alto=0;
               incremento_byte++;
               start=1;
              intcon.gpif=0;

     }
     }

    }

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void main() {                  ///////
incremento_byte=0;
stop_tempo=0;
alto=0;
basso=0;
start=0;
stop=0;
flag_discesa=0;
  leggi=0;
flag_salita=0;
inizio_ricezione=0;
tempo_trascorso=0;
   CMCON =  7;                         //Disabilita comparatore
   ADCON0 = 0b000000000;                //Disabilita convertitore A/D
   ANSEL =  0b00000000;                //Tutte le porte in digitale
   TRISIO = 0b00010000;                //Tutti i pin in OUT tranne gpio3
   OPTION_REG=0b00000101;              //abilita presaler 1:64 in modo da avere  un incremento del tmr0 ogni 64uS
    ioc=0b010000;
   INTCON.GPIE   =1;                   //abilita interrupt generale

  gpio.f5=0;
  gpio.f3=0;
  gpio.f2=0;
  gpio.f1=0;
  gpio.f0=0;
while(1){
////////////////////////////controlla impulso start di 13ms////////////////////////////////////////////////////////////

if(gpio.f4==0)
{
INTCON.T0IE=1;
tmr0=0;
flag_discesa=1;
}
if((gpio.f4==1)&&(flag_discesa==1))
{
flag_salita=1;
}
if((gpio.f4==0)&&(flag_salita==1))
{
tempo_trascorso=tmr0;
}
if(tempo_trascorso>200)
{
    intcon.GIE=1;
inizio_ricezione=1;
flag_salita=0;
flag_discesa=0;
tempo_trascorso=0;

}

if((inizio_ricezione==1)&&(start==1)){


if((tempo_trascorso<25)&&(stop_tempo==1))
              {

               ricevo[incremento_byte]=0;
              }
              if((tempo_trascorso>25)&&(stop_tempo==1))
              {
              ricevo[incremento_byte]=1;
              }
              }
         
         
         if(incremento_byte>20)
         {
           leggi=1;
           incremento_byte=0;
           intcon.gie=0;
           }
           if(leggi==1)
           {
           gpio.f2=1;
           stop++;
         gpio.f5=ricevo[incremento_byte];
         delay_ms(500);
         gpio.f2=0;
         delay_ms(500);
         incremento_byte++;
         }

             
             


}
}

Il codice sopra ancora non è ottimizzato e finito quindi alcune righe sono per fare il debug.
Ora sto cercando di copiare il codice in un array per poi ritrasmetterlo su di un led (gpio.f5). Il fatto è che ora una volta acquisita la stringa il gpio.f5 rimane sempre acceso, è come se nella stringa non ci fosse neanche uno zero, cosa improbabile
Avatar utente
Foto Utentesorecaro
36 3 7
Frequentatore
Frequentatore
 
Messaggi: 233
Iscritto il: 26 feb 2013, 19:30

0
voti

[14] Re: PIC e ricezione telecomandoinfrarossi

Messaggioda Foto UtenteIlGuru » 6 ott 2015, 17:06

Prova questo, l'ho fatto su xc8 ma si traduce facilmente:
Codice: Seleziona tutto
/*
* File:   main.c
* Author: sbusnelli
*
* Created on 6 ottobre 2015, 16.08
*/

#include <xc.h>

// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.

// CONFIG
#pragma config FOSC = INTRCIO   // Oscillator Selection bits (INTOSC oscillator: I/O function on GP4/OSC2/CLKOUT pin, I/O function on GP5/OSC1/CLKIN)
#pragma config WDTE = ON        // Watchdog Timer Enable bit (WDT enabled)
#pragma config PWRTE = OFF      // Power-Up Timer Enable bit (PWRT disabled)
#pragma config MCLRE = ON       // GP3/MCLR pin function select (GP3/MCLR pin function is MCLR)
#pragma config BOREN = ON       // Brown-out Detect Enable bit (BOD enabled)
#pragma config CP = OFF         // Code Protection bit (Program Memory code protection is disabled)
#pragma config CPD = OFF        // Data Code Protection bit (Data memory code protection is disabled)

typedef unsigned char   uchar;

uchar  samples[20];

int main(int argc, char** argv) {

    uchar i_sample  = 0;
    uchar timer1    = 0;
    uchar timer2    = 0;

    //  Interrupt disabilitati
    INTCONbits.GIE = 0;

    //  GP4 come Input
    TRISIObits.TRISIO4  = 1;
    //  GP5 come Output
    TRISIObits.TRISIO5  = 0;

    //  Usiamo TMR0 in modalità TIMER
    OPTION_REGbits.T0CS = 0;        //  Internal instruction cycle clock
    OPTION_REGbits.PSA  = 0;        //  Prescaler su TMR0
    OPTION_REGbits.PS   = 0b101;    //  Prescaler 1 : 64

    //  SKIP 1 iniziali
    while ( GPIObits.GP4 == 1 )
    {
        ;
    }
    //  SKIP 0 successivi agli 1 iniziali
    while ( GPIObits.GP4 == 0 )
    {
        ;
    }

    for ( i_sample=0; i_sample<20; i_sample++ ) {
        timer1 = TMR0;
        //  Misuro 1
        while ( GPIObits.GP4 == 1 )
        {
            ;
        }
        timer2 = TMR0;
        samples[i_sample] = timer2-timer1;
        //  SKIP 0
        while ( GPIObits.GP4 == 0 )
        {
            ;
        }
    }

    //  Visualizzo i valori
    for ( i_sample=0; i_sample<20; i_sample++ ) {
        if ( samples[i_sample] < 12 ) {
            //  Se il periodo misurato è inferiore a 12*64us=768us ~800us è uno 0, altrimenti è un 1
            GPIObits.GP5 = 0;
        } else {
            GPIObits.GP5 = 1;
        }
        _delay(1000000);
    }

    return 0;
}


Come discriminante tra gli 0 e gli 1 ho usato 800 \mu s ed ho tolto di mezzo gli interrupt
\Gamma\nu\tilde{\omega}\theta\i\ \sigma\epsilon\alpha\upsilon\tau\acute{o}\nu
Avatar utente
Foto UtenteIlGuru
4.134 1 10 13
Master
Master
 
Messaggi: 1372
Iscritto il: 31 lug 2015, 23:32

0
voti

[15] Re: PIC e ricezione telecomando infrarossi

Messaggioda Foto Utentesorecaro » 7 ott 2015, 20:25

Foto UtenteIlGuru grazie per l'aiuto, ho tradotto il tuo codice per mikroc ma non funziona, anche lui vede tutti "uno"
Avatar utente
Foto Utentesorecaro
36 3 7
Frequentatore
Frequentatore
 
Messaggi: 233
Iscritto il: 26 feb 2013, 19:30

0
voti

[16] Re: PIC e ricezione telecomando infrarossi

Messaggioda Foto Utentesorecaro » 7 ott 2015, 21:03

Sto testando questo codice con oscilloscopio. Canale A oscilloscopio collegato all'uscita del ricevitore infrarossi, canale B collegato al pin GPIO.F1 del PIC, sono identiche, quindi il PIC riceve perfettamente il dato, il problema è la memorizzazione del dato in array
Codice: Seleziona tutto

signed short ricevo[20]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
unsigned bit flag_discesa; flag_salita; inizio_ricezione;  alto; basso;
unsigned bit stop_tempo; leggi; stop; start;
unsigned short tempo_trascorso;
unsigned short incremento_byte;

void interrupt(void){

     if(intcon.gpif){

           if((gpio.f4==1)&&(alto==0))
              {
              gpio.f1=1;                                             //oscilloscopio canale B
               INTCON.T0IE=1;
              tmr0=0;
              stop_tempo=0;
              tempo_trascorso=0;
              alto=1;
              start=0;
              intcon.gpif=0;
              }
              if((gpio.f4==0)&&(alto==1))
              {
              gpio.f1=0;                                        //oscilloscopio canale B
              tempo_trascorso=tmr0;
              INTCON.T0IE=0;
              stop_tempo=1;
              alto=0;
               incremento_byte++;
               start=1;
              intcon.gpif=0;

     }
     }

    }

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void main() {                  ///////
incremento_byte=0;
stop_tempo=0;
alto=0;
basso=0;
start=0;
stop=0;
flag_discesa=0;
  leggi=0;
flag_salita=0;
inizio_ricezione=0;
tempo_trascorso=0;
   CMCON =  7;                         //Disabilita comparatore
   ADCON0 = 0b000000000;                //Disabilita convertitore A/D
   ANSEL =  0b00000000;                //Tutte le porte in digitale
   TRISIO = 0b00010000;                //Tutti i pin in OUT tranne gpio3
   OPTION_REG=0b00000101;              //abilita presaler 1:64 in modo da avere  un incremento del tmr0 ogni 64uS
    ioc=0b010000;
   INTCON.GPIE   =1;                   //abilita interrupt generale

  gpio.f5=0;
  gpio.f3=0;
  gpio.f2=0;
  gpio.f1=0;
  gpio.f0=0;
while(1){
////////////////////////////controlla impulso start di 13ms////////////////////////////////////////////////////////////

if(gpio.f4==0)
{
INTCON.T0IE=1;
tmr0=0;
flag_discesa=1;
}
if((gpio.f4==1)&&(flag_discesa==1))
{
flag_salita=1;
}
if((gpio.f4==0)&&(flag_salita==1))
{
tempo_trascorso=tmr0;
}
if(tempo_trascorso>200)
{
    intcon.GIE=1;
inizio_ricezione=1;
flag_salita=0;
flag_discesa=0;
tempo_trascorso=0;

}
}
}

Come posso migliorare la memorizzazione del dato??
Avatar utente
Foto Utentesorecaro
36 3 7
Frequentatore
Frequentatore
 
Messaggi: 233
Iscritto il: 26 feb 2013, 19:30

0
voti

[17] Re: PIC e ricezione telecomando infrarossi

Messaggioda Foto UtenteIlGuru » 7 ott 2015, 21:16

Credo che ogni volta che nella routine di interrupt fai

tmr0=0;

resetti il prescaler che quindi non divide più per 64 la frequenza con cui si incrementa il timer.
\Gamma\nu\tilde{\omega}\theta\i\ \sigma\epsilon\alpha\upsilon\tau\acute{o}\nu
Avatar utente
Foto UtenteIlGuru
4.134 1 10 13
Master
Master
 
Messaggi: 1372
Iscritto il: 31 lug 2015, 23:32

0
voti

[18] Re: PIC e ricezione telecomando infrarossi

Messaggioda Foto UtentePaolino » 7 ott 2015, 21:30

Secondo me c'è un po' di confusione.
Il controllo della polarità della porta lo devi fare solamente nell'interrupt. L'ho parzialmente modificata la ISR dell'interrupt:

Codice: Seleziona tutto
void interrupt(void)
{

   if(intcon.gpif)
   {
      if((gpio.f4==1)&&(alto==0))
      {
         gpio.f1=1;                                             //oscilloscopio canale B
         INTCON.T0IE=1;
         tmr0=0;
         stop_tempo=0;
         tempo_trascorso=0;
         alto=1;
         start=0;
      } else if((gpio.f4==0)&&(alto==1))
      {
         gpio.f1=0;                                        //oscilloscopio canale B
         tempo_trascorso=tmr0;
         INTCON.T0IE=0;
         stop_tempo=1;
         alto=0;
         incremento_byte++;
         start=1;
      }
      intcon.gpif=0;
   }

}


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: 4186
Iscritto il: 20 gen 2006, 11:42
Località: Vigevano (PV)

0
voti

[19] Re: PIC e ricezione telecomando infrarossi

Messaggioda Foto Utentesorecaro » 7 ott 2015, 21:55

resetti il prescaler che quindi non divide più per 64 la frequenza con cui si incrementa il timer

Foto UtenteIlGuru impostando il tmr0 a 0 non resetti il prescaler, ma solo il conteggio del timer. Il prescaler viene impostato dal registro OPTION REG
Avatar utente
Foto Utentesorecaro
36 3 7
Frequentatore
Frequentatore
 
Messaggi: 233
Iscritto il: 26 feb 2013, 19:30

0
voti

[20] Re: PIC e ricezione telecomando infrarossi

Messaggioda Foto UtenteIlGuru » 7 ott 2015, 22:25

sorecaro ha scritto:impostando il tmr0 a 0 non resetti il prescaler


Scusami, il datasheet forse in merito è un po' ambiguo:

Capitolo 4, paragrafo 4.4 "Prescaler":

When assigned to the Timer0 module, all instructions writing to the TMR0 register (e.g., CLRF 1, MOVWF 1, BSF 1, x....etc.) will clear the prescaler.

A questo punto vorrei fare degli esperimenti in merito, non capisco se si resetta un contatore interno del prescaler, o proprio l'impostazione.
\Gamma\nu\tilde{\omega}\theta\i\ \sigma\epsilon\alpha\upsilon\tau\acute{o}\nu
Avatar utente
Foto UtenteIlGuru
4.134 1 10 13
Master
Master
 
Messaggi: 1372
Iscritto il: 31 lug 2015, 23:32

PrecedenteProssimo

Torna a Firmware e programmazione

Chi c’è in linea

Visitano il forum: Nessuno e 1 ospite