interrupt on change su fotocellule che non cancella RBIF e TEMPO DI RIPRESA

3 Anni 6 Mesi fa - 3 Anni 6 Mesi fa #1 da Elby
Ho progettato una scheda che, oltre a tante altre funzioni, controlla gli ingressi di una lavanderia automatica.
Prima di tutto spiego il problema.
Il sistema effettua regolarmente il conteggio delle persone in aumento e decremento. Tra la fotocellula di ingresso e la fotocellula di uscita ho inserito un timer a 4 secondi per far avvenire il transito.
Quello che avviene è questo.

ATTRAVERSO una delle due fotocellule: il sistema si ferma per 4 secondi in attesa che ATTRAVERSI anche l'altra fotocellula. Questo avviene perchè il RBIF non si è cancellato e quindi esce e rientra continuamente nell'interrupt.

MI FERMO sulla fotocellula a tempo indefinito (quindi lo stato dell'ingresso RBx è fisso e non cambia), il sistema resta bloccato fino a che non libero l'ingresso, poi attende i 4 secondi di sopra ed infine si sblocca.
Fondamentalmente so che il problema sta nel bir RBIF che non si sta azzerando ma non capisco come mai visto che addirittura faccio due letture della porta e l'azzeramento forzato.

Per il conteggio delle persone ho usato (su un PIC18F46K22) gli ingressi RB6 ed RB7 che sono provvisti di weak pull-up,e di interrupt on change. Ho quindi inizializzato gli ingressi in questo modo:

TRISB=0b11000000; //tutte uscite tranne RB6 ed RB7 ce sono le fotocellule
ANSELB=0x00; //portB tutta digitale
INTCON2bits.nRBPU=0; //abilita la possibilità di weak pull up sulla porta B
WPUB=0b11000000; //weak pull-up sugli ingressi RB6,RB7 delle fotocellule (sulla scheda ho anche delle pull-up da 10K)
LATB=0b11000000; //registri LAT portati 0 ad eccezione delle fotocellule
PORTBbits.RB6=1;
PORTBbits.RB7=1;

ed ho abilitato gli interrupt on change sui singoli ingressi e sul registri INTCON

IOCBbits.IOCB7=1; //abilita interrupt on change sui pin RB7 ed RB6
IOCBbits.IOCB6=1;
INTCONbits.RBIF=0; //azzera flag di interrupt on change
INTCONbits.RBIE=1; //inizializza interrupt di change degli ingressi

andiamo a questo punto alla routune di interrupt

if ((INTCONbits.RBIF==1)&&(INTCONbits.RBIE==1))
{delay_ms(200); //anti bump
STATO_FOTOCELLULA_INGRESSO=PORTBbits.RB7; //leggi la fotocellula di ingresso (esterna al negozio)
STATO_FOTOCELLULA_USCITA=PORTBbits.RB6; //leggi la fotocellula di uscita (interna al negozio)
if ((STATO_FOTOCELLULA_INGRESSO==PASSAGGIO_PERSONA)&&(STATO_FOTOCELLULA_USCITA==STATO_DI_RIPOSO)&&(PERSONA_IN_USCITA==0))
{Accendi_Timer3();
PERSONA_IN_ENTRATA=1;
}
if ((STATO_FOTOCELLULA_INGRESSO==PASSAGGIO_PERSONA)&&(STATO_FOTOCELLULA_USCITA==STATO_DI_RIPOSO)&&(PERSONA_IN_USCITA==1))
{Spegni_Timer3();
PERSONA_IN_ENTRATA=0; //aggiunta dopo
PERSONA_IN_USCITA=0;
if (NUMERO_PERSONE_PRESENTI>0)
{NUMERO_PERSONE_PRESENTI--;
Visualizza_Persone ();
}
}
if ((STATO_FOTOCELLULA_INGRESSO==STATO_DI_RIPOSO)&&(STATO_FOTOCELLULA_USCITA==PASSAGGIO_PERSONA)&&(PERSONA_IN_ENTRATA==0))
{Accendi_Timer3();
PERSONA_IN_USCITA=1;
}
if ((STATO_FOTOCELLULA_INGRESSO==STATO_DI_RIPOSO)&&(STATO_FOTOCELLULA_USCITA==PASSAGGIO_PERSONA)&&(PERSONA_IN_ENTRATA==1))
{Spegni_Timer3();
NUMERO_PERSONE_PRESENTI++;
PERSONA_IN_ENTRATA=0;
PERSONA_IN_USCITA=0; //aggiunta dopo
if (NUMERO_PERSONE_PRESENTI>=100)
{NUMERO_PERSONE_PRESENTI=0;
}
Visualizza_Persone ();
}
STATO_FOTOCELLULA_INGRESSO=PORTBbits.RB7; //leggi la fotocellula di ingresso (esterna al negozio)
STATO_FOTOCELLULA_USCITA=PORTBbits.RB6; //leggi la fotocellula di uscita (interna al negozio)
delay_ms(100); //una generica istruzione richiesta sul datasheet prima di cancellare RBIF
INTCONbits.RBIF=0;
}

per quanto ne so e leggo sul datasheet, già solo le istruzioni in neretto basterebero a cancellare RBIF
Ultima Modifica 3 Anni 6 Mesi fa da Elby.

Si prega Accedi o Crea un account a partecipare alla conversazione.

  • Elby
  • Senior Member
  • Senior Member
Di più
3 Anni 6 Mesi fa #2 da firstcolle
ho sempre trovato odiosi gli interrupt on change soprattutto perchè raramente riesco a farli funsionare... se non ricordo male c'è pure un bud dove se non resettati in un certo modo restano il flag non si resetta (e mi pare il tuo caso).

però non riesci a cambiarlo con un interrupt su falling o risnig edge?? alla fine a te serve vedere quando la fotocellula da stato di riposo (presumiamo alto) vada a stato basso.. non penso ti serva un interrupt anche quando la fotocellula da basso torni a stato alto.

avevo fatto anche io un progettino cosi millenni fa, ancora in assembly ma non ricordo come avevo implementato tutto

Si prega Accedi o Crea un account a partecipare alla conversazione.

  • firstcolle
  • Avatar di firstcolle
  • Platinum Member
  • Platinum Member
Di più
3 Anni 6 Mesi fa #3 da Elby
Su altri pic ho utilizzato solo il falling edge ma il pic 18f46k22 ha solo il registro ioc che tiene conto dell'ultimo stato di lettura sulla porta....peccato che a me nonostante legga la porta e azzeri il flag, questo non venga fatto

Si prega Accedi o Crea un account a partecipare alla conversazione.

  • Elby
  • Senior Member
  • Senior Member
Di più
3 Anni 6 Mesi fa #4 da firstcolle
dovrebbe averli su RB0-RB1-RB2, peccato che hai messo le forocellule su RB6-7.. spostarle?
ora vedo se trovo il documento con il bug

Si prega Accedi o Crea un account a partecipare alla conversazione.

  • firstcolle
  • Avatar di firstcolle
  • Platinum Member
  • Platinum Member
Di più
3 Anni 6 Mesi fa #5 da firstcolle
So, we must read PORTB first, to clear the difference which got us here in the first place, and then clear RBIF, then read PORTB again (without clearing RBIF) to insure that any change on the pins between Q1 and Q3 that instruction is detected.

In numbered sequence ...
Read PORTB first to latch the current value from the pins into the PORTB latch and possibly into the change detection latch. In most cases, both values will be the same.
Clear RBIF. If both latches have the same value at this point, RBIF will stay clear.
Read PORTB again after clearing RBIF. If the value on the PIN changes between Q1 and Q3, RBIF will be set again automaticly and this is good because the value most recently read from PORTB is not the value currently on the pins. Another interrupt will occur as soon as we return from this one

Si prega Accedi o Crea un account a partecipare alla conversazione.

  • firstcolle
  • Avatar di firstcolle
  • Platinum Member
  • Platinum Member
Di più
Moderatori: Mauro LaurentiPinnaStefAMatteo Garia

Registrati al sito

Accedi a tutte le risorse e articoli non visibili pubblicamente, puoi registrarti con pochi passi.

Registrati al sito LaurTec.

Login