PIC18: Disabilitare gli Interrupt nella ISR
Sono arrivato al punto di dover leggere un encoder incrementale; ma il problema che mi trovo ad affrontare è sulla gestione degli interrupt.
La scheda che sto preparando ad un certo punto del main deve eseguire le seguenti operazioni:
1 - Accendere un motore (porto ad 1 la porta collegata ai driver del relè);
2 - Per ognuno di N intervalli di tempo di durata T: Contare gli impulsi in uscita dall'encoder e definire il verso di rotazione e salvare i dati in un array;
3 - Spegnere il motore;
4 - Andare avanti con il programma.
Il punto 2 avevo pensato di risolverlo così (sono ovviamente graditi suggerimenti/osservazioni):
2a - abilito interrupt su TMR0 (alta priorità) ed INT1 (bassa priorità).
2b - TMR0 genera interrupt ogni periodo T ed incrementa una variabile conteggio; quando questa arriva ad N ALL'INTERNO DELLA ISR VENGONO DISABILITATI GLI INTERRUPT (INTCONbits.GIE/GIEL = 0).
2c - INT1 incrementa la variabile di conteggio impulsi e con confronto sull'altro canale dell'encoder determina il senso di rotazione.
Ora il problema è che quando all'interno della ISR del TMR0 disabilito gli interrupt con le isruzioni:
INTCONbits.GIEH = 0; // DISAbilito gli interrupt ad alta priorità
INTCONbits.GIEL = 0; // DISAbilito gli interrupt a bassa priorità
ill programma tornando al main in automatico imposta il bit INTCON.GIE ad 1 (lo stesso comportamento si ha con INTCON.GIEL).
In sostanza il PIC quando entra in una ISR, porta il bit GIEH/GIEL corrispondente a 0 (immagino per non entrare nel loop di risposta allo stesso interrupt) e poi lo riporta ad 1 al termine della funzione; ma questo comporta l'impossibilità di cambiare lo stato dei GIEH/GIEL all'interno della ISR.
Chiedo questo comportamento che ho osservato è normale?
Sapete se per caso le modifiche fatte sugli SFR all'interno delle funzioni sono valide solo nello scope delle funzioni stesse?
Nel datasheet non ho trovato riferimenti a questo comportamento, ma può essermi scappato.
Il fenomeno si presenta sia in RELEASE che in DEBUG (nella finestra Watch si vede proprio il bit GIEH/GIEL che nel ritorno al main passa ad 1!).
Thanks in advance!
Antonio
P.S. Se necessario vi posto il codice che è piuttosto lungo per via delle impostazioni del TMR0 e delle ISR.
Si prega Accedi o Crea un account a partecipare alla conversazione.
- Stanzione
- Autore della discussione
- Visitatori
Ciao
Antonio
Si prega Accedi o Crea un account a partecipare alla conversazione.
- Stanzione
- Autore della discussione
- Visitatori
una cosa come questa non la puoi prendere per scontata o arrivarci.
Riattivare o meno gli interrupt e' una specifica.
In particolare sulla pagina del datasheet relativa alle interruzioni e' scritto:
The return address is pushed onto the stack and the
PC is loaded with the interrupt vector address
(000008h or 000018h). Once in the Interrupt Service
Routine, the source(s) of the interrupt can be determined
by polling the interrupt flag bits. The interrupt
flag bits must be cleared in software before re-enabling
interrupts to avoid recursive interrupts.
The “return from interrupt” instruction, RETFIE, exits
the interrupt routine and sets the GIE bit (GIEH or GIEL
if priority levels are used) which re-enables interrupts.
Per cui oltre all'intdirrizzo vengono riabilitate le interruzioni. Le interruzioni sulle periferiche non sono riabilitate per cui se vuoi che una periferica non generi piu' interrupt puoi disabilitare il suo bit dedicato alle interruzioni e non fare affidamento al General Interruprt Enable.
Saluti,
Mauro
Si prega Accedi o Crea un account a partecipare alla conversazione.
- Mauro Laurenti
- Moderator
Infatti bastava leggere il datasheet... e adesso che lo riguardo vedo che avevo sottolineato proprio quel paragrafo!
Ciao
Antonio
Si prega Accedi o Crea un account a partecipare alla conversazione.
- Stanzione
- Autore della discussione
- Visitatori
Registrati al sito
Accedi a tutte le risorse e articoli non visibili pubblicamente, puoi registrarti con pochi passi.