In questa pagina verrà mostrato come gestire in assembly le interruzioni con priorità del PIC18 generate da sorgenti esterne, quale un semplice interruttore. Qui una breve descrizione del concetto di interruzione.
Al solito, è vivamente consigliata la lettura in parallelo della spiegazione semplificata qui riportata e della la spiegazione "ufficiale" presente nei fogli tecnici.
Il PIC18 prevede due distinte modalità di uso delle interruzioni:
L'hardware di riferimento è il PICdemo oppure il PICdemo R2 anche se il circuito è realizzabile senza alcun problema direttamente su breadboard. In particolare vengono utilizzati:
Quando le interruzioni del PIC18 sono configurate in Priority mode è possibile definire due classi di priorità:
La differenza essenziale tra le due è che le seconde possono interrompere l'esecuzione delle prime, ma non viceversa.(nota 1).
La priorità delle interruzioni generate da una specifica periferica è in genere programmabile, a seconda delle esigenze.
A fondo pagina trovate il codice che utilizza un interrupt ad alta priorità ed uno a bassa priorità. In particolare:
Per la gestione vengono utilizzati diversi flag, distribuiti su vari registri:
Il codice di inizializzazione delle porte è sostanzialmente identico all'esempio relativo alla modalità compatibile, con la sola aggiunta della configurazione di INT1 come ingresso con pull-up:
clrf TRISC ; PORTC come uscita, tutti gli 8 pin
movlw 0x01 ; LED0 acceso; LED1-7 spenti
movwf LATC
movlw 0xFF ; PORTB come ingresso, tutti gli 8 pin
movwf TRISB
bsf WPUB, INT0 ; abilita il pull-up interno su INT0
bsf WPUB, INT1 ; abilita il pull-up interno su INT1
bcf INTCON2, RBPU ; Pull-up attivo su tutti i pin abilitati
Occorre quindi procedere alla configurazioni delle interruzioni, impostando:
Il codice corrispondente:
bsf RCON, IPEN ; Abilito le interruzioni a livelli di
priorità
bsf INTCON, INT0IE ; Abilito INT0 a generare interruzioni (ad alta priorità)
bcf INTCON3, INT1IP ; Imposto INT1 a bassa priorità
bsf INTCON3, INT1IE ; Abilito INT1 a generare interruzioni
bsf INTCON, GIEH ; Abilito la CPU a ricevere interruzioni ad alta priorità
bsf INTCON, GIEL ; Abilito la CPU a ricevere interruzioni a bassa priorità
Dopo le configurazioni iniziali, il processore inizia un ciclo infinito dove non vene fatto assolutamente nulla di significativo. In particolare il codice NON legge il valore dell'interruttore e NON imposta l'accensione dei LED.
repeat
nop ; non fa nulla (No OPeration), per sempre
nop
bra repeat
Questa ISR è il codice che viene eseguito quando l'hardware rileva la generazione di un interrupt ad alta priorità. La descrizione è identica a quanto già scritto a proposito delle interruzioni senza priorità, a cui si rimanda. In particolare non cambia l'indirizzo in cui il codice deve essere memorizzato (0x0008) e la modalità di salvataggio e recupero dei registri nei registri shadow.
Il codice:
ISR_Alta CODE 0x0008 ; Vettore per ISR ad alta priorità
goto AltaPriorita ; Salta all'inizi della ISR ad alta priorità
Interruzioni CODE ; Codice per la gestione delle
interruzioni
AltaPriorita
btfsc INTCON, INT0IF ; Interruzione causata da INT0 ?
bra GestioneINT0 ; Esegue il codice corrispondente
retfie FAST ; Nessuna fleg settato... Indizio di un errore?
GestioneINT0
rlncf LATC ; "Ruota" i LED
bcf INTCON, INT0IF ; Azzera il flag che segnala INT0
retfie FAST ; Torna ad eseguire il codice principale
L'unica cosa che è bene mettere in evidenza è che questo codice non può essere mai interrotto.
Due sono le differenze fondamentali rispetto alla ISR ad alta priorità:
Il codice:
ISR_Bassa CODE 0x0018 ; Vettore per ISR a bassa priorità
goto BassaPriorita ; Salta all'inizi della ISR bassa priorità
BassaPriorita
movff WREG, WREG_TEMP ; salva il registro W nella variabile "temporanea"
movff STATUS, STATUS_TEMP ; salva i flag nella variabile "temporanea"
movff BSR, BSR_TEMP ; salva il registro BSR nella variabile "temporanea"
btfsc INTCON3, INT1IF ; Interruzione causata da INT1 ?
bra GestioneINT1 ; Esegue il codice corrispondente
bra Ritorna ; Nessuna fleg settato... Indizio di un errore?
GestioneINT1
bcf INTCON3, INT1IF ; Azzera il flag che segnala INT1
movlw 0x01 ; LED0 acceso; LED1-7 spenti (situazione iniziale)
movwf LATC
bra Ritorna
Ritorna
movff STATUS_TEMP, STATUS ; ripristina i flags
movff WREG_TEMP, WREG ; ripristina il registro W
movff BSR_TEMP, BSR ; ripristina il registro BSR
retfie
Ultima modifica di questa pagina: 21 maggio 2016 - Una pagina simile: Le interruzioni nel PIC18 (in C)
Assembly PIC18 - Versione 0.5 - aprile 2018
Copyright 2016-2018, Vincenzo Villa (https://www.vincenzov.net)
Assembly PIC18 di Vincenzo Villa è distribuito con Licenza Creative Commons Attribuzione 4.0 Internazionale