Programmare in mikroBasic
 
  Box
Uso dell'interrupt
(parte 4)

Sommario

Per le informazioni riferite a questo argomento e per compilare i programmi è stata usata la vers. 7.0.0.2 di mikroBasic.
Altre versioni del compilatore potrebbero avere comportamenti diversi o non funzionare.

Interrupt nel PIC16F877A

Alcune caratteristiche dei PIC16F877A (873A, 874A, 876A).

16F... Pin Flash RAM Eeprom I/O Timer Clock
interno
CCP ADC Comp Usart LVP Costo
873A 28 4k 192 128 22 3 No 2 5 2 Usart
SPI
I2C
Si €3,81
874A 40 4k 192 128 33 3 No 2 8 2 Usart
SPI
I2C
Si €4,16
876A 28 8k 368 256 22 3 No 2 5 2 Usart
SPI
I2C
Si €4,18
877A 40 8k 368 256 33 3 No 2 8 2 Usart
SPI
I2C
Si €4,43

Vediamo gli interrupt che possono essere gestiti dal PIC16F877A (873A, 874A, 876A).

Sorgente di Interrupt
(16F877A)
Registri coinvolti Bit di Enable (abilitaz.) Bit di Flag (segnalaz.) Note
Cambio stato ingressi PORTB.4, PORTB.5, PORTB.6, PORTB.7 INTCON RBIE RBIF  
Cambio stato ingresso PORTB.0 INTCON, OPTION_REG INTE INTF Possibilità di scegliere fronte di salita o discesa
Overflow TMR0 (Timer zero) INTCON TMR0IE TMR0IF  
Overflow TMR1 (Timer 1) PIE1, PIR1 TMR1IE TMR1IF  
TMR2 uguale a PR2 (Timer 2) PIE1, PIR1 TMR2IE TMR2IF  
Capture/Compare CCP1 interrupt PIE1, PIR1 CCP1IE CCP1IF  
Porta Seriale Sincrona (SSP) PIE1, PIR1 SSPIE SSPIF  
Trasmissione USART PIE1, PIR1 TXIE TXIF  
Ricezione USART PIE1, PIR1 RCIE RCIF  
Conversione A/D completata PIE1, PIR1 ADIE ADIF  
Porta parallela slave (PSP) PIE1, PIR1 PSPIE PSPIF  
Capture/Compare CCP2 interrupt PIE2, PIR2 CCP2IE CCP2IF  
Collisione bus in SSP PIE2, PIR2 BCLIE BCLIF  
Scrittura EEPROM completata PIE2, PIR2 EEIE EEIF  
Cambio stato Comparatori PIE2, PIR2 CMIE CMIF  

Il PIC16F877A contiene moduli di periferica, quindi sono presenti, oltre al registro INTCON, anche i registri PIE1, PIE2, PIR1 e PIR2, che permettono la gestione degli interrupt tramite l'impostazione di alcuni bit specifici.

   

Confrontando il registro INTCON con quello del PIC16F84A, notiamo che il bit 6 ha un'altro nome: PEIE.

Il bit PEIE abilita, se messo a 1, tutte le interruzioni abilitate (non mascherate), dei moduli di periferica.
Se messo a 0, invece, blocca tutte le interruzioni generate dai moduli di periferica.
Dopo un reset o quando viene data alimentazione al circuito, questo bit viene messo a 0.

Il bit GIE ha sempre la funzione di bloccare o sbloccare tutte le interruzioni.

Gli altri bit del registro INTCON hanno le stesse funzioni come viste nel 16F84A (anche se cambiano nome).

Il bit EEIE, che abilita l'interruzione su fine scrittura EEprom, che, nel 16F84A, si trovava nel registro INTCON, è stato spostato nel registro PIE2.
I registri Peripheral Interrupt Enable (PIE1 e PIE2), contengono i bit di abilitazione individuali per gli interrupt dei moduli di periferica.
Se un bit viene messo a 1, verrà abilitato l'interrupt del modulo di periferica associato a quel bit.
Se messo a 0, verrà disabilitato (si dice, anche, mascherato), l'interrupt per quella periferica.
Dopo un reset o quando viene data alimentazione al circuito, tutti i bit sono messi a 0.

   
   

I registri Peripheral Interrupt Flag (PIR1 e PIR2), contengono i bit di flag individuali per gli interrupt dei moduli di periferica. Il bit di flag d'interrupt di una periferica viene messo a 1 quando si verifica una condizione d'interruzione per quella periferica.
I bit RCIF e TXIF sono di sola lettura, vengono settati o azzerati solo dall'hardware interno.

   
   

Per abilitare una interruzione di un modulo di periferica, non basta abilitarla nei registri PIE1 e PIE2, ma bisogna anche ricordarsi di mettere a 1 il bit PEIE del registro INTCON.

Vediamo ora, in dettaglio, come possiamo gestire e controllare i vari eventi con mikroBasic.

Cambio stato ingressi PORTB.4, PORTB.5, PORTB.6, PORTB.7
Questo è un interrupt esterno generato dagli ingressi PORTB.4, PORTB.5, PORTB.6, PORTB.7 che avviene quando, su almeno uno di questi ingressi, viene riscontrato un cambiamento di stato.
Questo interrupt può risvegliare il PIC dallo stato SLEEP.
Se qualcuno dei pin PORTB.4, PORTB.5, PORTB.6, PORTB.7 viene configurato come uscita anziché come ingresso, viene automaticamente escluso dalla possibilità di generare una interruzione.

program prova_Int_1
' 16F877A - 8MHz

sub procedure interrupt
    if testbit(INTCON,RBIF) then
        if testbit(PORTB,4) then
            setbit(PORTB,2)
        end if
        if testbit(PORTB,5) then
            clearbit(PORTB,2)
        end if
        clearbit(INTCON,RBIF)
    end if
end sub

sub procedure pausa1000
    delay_ms(1000)
end sub

main:
    PORTA = 0
    ADCON1 = %00000110      'portA digitale
    TRISA = %00000
    PORTB = 0
    TRISB = %00110000
    setbit(INTCON,RBIE) 'interr. portb.4, 5, 6, 7
    setbit(INTCON,GIE)  'abilita tutti interrupt
    while true
        setbit(PORTA,0)
        pausa1000
        clearbit(PORTA,0)
        pausa1000
    wend
End.

Dopo l'etichetta main, impostiamo PORTA come uscita, PORTB.4 e PORTB.5 come ingressi, il resto come uscite.

Impostiamo a 1 il bit RBIE di INTCON, abilitando le interruzioni sul cambio stato degli ingressi PORTB.4, PORTB.5, PORTB.6 e PORTB.7.
Essendo, PORTB.6 e PORTB.7, uscite, non potranno generare interrupt.

Impostiamo a 1 il bit GIE di INTCON per abilitare tutti gli interrupt.

Facciamo lampeggiare un LED, con cadenza di circa 1 secondo, su PORTA.0.

A questo punto, quando verrà generato un'interruzione qualunque, il programma interromperà l'esecuzione e salterà all'indirizzo del vettore di interrupt dove c'è la sub procedura interrupt ed eseguirà il test del bit RBIF di INTCON.
Se questo bit sarà a 1, si eseguiranno le istruzioni per individuare quale ingresso (PORTB.4 o PORTB.5) ha causato l'interrupt e si eseguiranno le istruzioni predisposte.

Prima di uscire dalla sub, azzeriamo il bit RBIF di INTCON.
Ora, il programma uscirà dalla sub e riprenderà l'esecuzione da dove era stata interrotta precedentemente.

Cambio stato ingresso PORTB.0 (RB0/INT)
Questo è un interrupt esterno generato dal piedino PORTB.0, che viene causato dal passaggio, da uno stato logico ad un altro, dell'ingresso PORTB.0.
Questo interrupt può risvegliare il PIC dallo stato SLEEP.
E' possibile far agire l'interrupt sia su un fronte di salita (passaggio da 0 a 1) che su un fronte di discesa (passaggio da 1 a 0).
L'una o l'altra modalità viene selezionata attraverso il bit INTEDG del registro OPTION_REG.

   

Se questo bit viene messo a 1, l'interrupt avviene in corrispondenza di un fronte di salita, mentre, se viene messo a 0, l'interrupt avviene in corrispondenza di un fronte di discesa.
Quando si alimenta il PIC o dopo un reset, questo bit viene messo a 1.

program prova_Int_2
' 16F877A - 8MHz

sub procedure interrupt
    if testbit(INTCON,INTF) then  'portb.0 int
        if testbit(PORTB,7) then
            clearbit(PORTB,7)
        else
            setbit(PORTB,7)
        end if
        clearbit(INTCON,INTF)
    end if
end sub

sub procedure pausa1000
    delay_ms(1000)
end sub

main:
    PORTA = 0
    ADCON1 = %00000110      'portA digitale
    TRISA = %00000
    PORTB = 0
    TRISB = %00000001
    setbit(INTCON,INTE) 'abil. interr. portb.0
    setbit(INTCON,GIE)  'abilita interrupt
    while true
        setbit(PORTB,2)
        pausa1000
        clearbit(PORTB,2)
        pausa1000
    wend
End.

Dopo l'etichetta main, impostiamo PORTB.0 come ingresso, il resto come uscite.

Impostiamo a 1 il bit INTE di INTCON, abilitando le interruzioni sul cambio stato dell'ingresso PORTB.0.

Impostiamo a 1 il bit GIE di INTCON per abilitare tutti gli interrupt.

Facciamo lampeggiare un LED, con cadenza di circa 1 secondo, su PORTB.2.

A questo punto, quando verrà generato un'interruzione qualunque, il programma interromperà l'esecuzione e salterà all'indirizzo del vettore di interrupt dove c'è la sub procedura interrupt ed eseguirà il test del bit INTF di INTCON.
Se questo bit sarà a 1, si eseguiranno le istruzioni predisposte.

Prima di uscire dalla sub, azzeriamo il bit INTF di INTCON.
Ora, il programma uscirà dalla sub e riprenderà l'esecuzione da dove era stata interrotta precedentemente.

Azzeramento di TMR0
Il TMR0 è il registro che tiene il conteggio del Timer0 ed avanza automaticamente durante l'esecuzione di un programma.
Il microcontrollore genera un'interrupt non appena il valore di tale registro supera il limite di 255, ossia al verificarsi del relativo overflow e quindi azzeramento.
Questo interrupt non risveglia il PIC dallo stato SLEEP perchè, in quel caso, il Timer0 viene spento.

program prova_Int_3
' 16F877A - 8MHz

dim conta as byte

sub procedure interrupt
    if testbit(INTCON,TMR0IF) then ' TMR0 int
        Inc(conta)
        TMR0 = 100
        clearbit(INTCON,TMR0IF)
    end if
end sub

main:
    PORTA = 0
    ADCON1 = %00000110      'portA digitale
    TRISA = %00000
    PORTB = %11111111
    TRISB = 0
    OPTION_REG = %11000101 'prescaler 1:64
    TMR0 = 100
    conta = 0
    setbit(INTCON,TMR0IE) ' TMR0
    setbit(INTCON,GIE)  'abilita interrupt

    while TRUE
        if conta = 200 then
            PORTB = not PORTB
            conta = 0
        end if
    wend
end.

Dopo l'etichetta main, impostiamo PORTB, il prescaler e il valore iniziale del registro TMR0.

Impostiamo a 1 il bit TMR0IE di INTCON, abilitando le interruzioni sull'azzeramento di TMR0.

Impostiamo a 1 il bit GIE di INTCON per abilitare tutti gli interrupt.

Tutta PORTB sarà impostata a 1. Ogni volta che la variabile conta arriva a 200, PORTB verrà invertito di stato.
Il risultato sarà che PORTB lampeggerà con cadenza di circa 1 secondo.
Quando verrà generato un'interruzione qualunque, il programma interromperà l'esecuzione e salterà all'indirizzo del vettore di interrupt dove c'è la sub procedura interrupt ed eseguirà il test del bit TMR0IF di INTCON.
Se questo bit sarà a 1, verrà incrementata la variabile conta e reimpostato il valore di partenza di TMR0.

Prima di uscire dalla sub, azzeriamo il bit TMR0IF di INTCON.
Ora, il programma uscirà dalla sub e riprenderà l'esecuzione da dove era stata interrotta precedentemente.

program prova_Int_6
' 16F877A - 8MHz

sub procedure interrupt
    if testbit(PIR1,TMR1IF) then
        ..... vostre istruzioni
        clearbit(PIR1,TMR1IF)
    end if
end sub

main:
    setbit(PIE1,TMR1IE) 'abil. interr. TMR1
    setbit(INTCON,PEIE) 'abil. interr. perif.
    setbit(INTCON,GIE)  'abil. tutti interrupt

    while TRUE
        ..... vostre istruzioni
    wend
end.

Azzeramento di TMR1

Il TMR1 è un registro a 16 bit (TMR1L - TMR1H) che tiene il conteggio del Timer1 ed avanza automaticamente durante l'esecuzione di un programma.

Il microcontrollore genera un'interrupt settando il bit di flag TMR1IF, in PIR1, non appena il valore, di tale registro, supera il limite di 65535, ossia al verificarsi del relativo overflow e quindi azzeramento.

program prova_Int_7
' 16F877A - 8MHz

sub procedure interrupt
    if testbit(PIR1,TMR2IF) then
        ..... vostre istruzioni
        clearbit(PIR1,TMR2IF)
    end if
end sub

main:
    setbit(PIE1,TMR2IE) 'abil. interr. TMR2
    setbit(INTCON,PEIE) 'abil. interr. perif.
    setbit(INTCON,GIE)  'abil. tutti interrupt

    while TRUE
        ..... vostre istruzioni
    wend
end.

Uguaglianza di TMR2 con PR2

Il TMR2 è un registro ad 8 bit che tiene il conteggio del Timer2, avente un prescaler ed un postscaler ed avanza automaticamente durante l'esecuzione di un programma.

Non appena il valore, di tale registro, supera il valore impostato nel registro PR2, viene reimpostato a 0 e viene generato un'impulso di incremento per il postscaler, il quale al verificarsi del relativo overflow e quindi azzeramento, setta il bit di flag di interrupt TMR2IF in PIR1.

program prova_Int_8
' 16F877A - 8MHz

sub procedure interrupt
    if testbit(PIR1,CCP1IF) then
        ..... vostre istruzioni
        clearbit(PIR1,CCP1IF)
    end if
end sub

main:
    setbit(PIE1,CCP1IE) 'abil. interr. CCP
    setbit(INTCON,PEIE) 'abil. interr. perif.
    setbit(INTCON,GIE)  'abil. tutti interrupt

    while TRUE
        ..... vostre istruzioni
    wend
end.

Interr. del modulo Capture/compare (CCP1)

Nella modalità CAPTURE, i registri CCPR1L e CCPR1H "catturano" il valore a 16 bit del timer TMR1 quando si verifica un determinato evento sul piedino CCP1.
Questo evento può essere:

un fronte di salita o di discesa
ogni 4 fronti di salita
ogni 16 fronti di discesa.

La modalità dell'evento viene determinata attraverso un registro di configurazione.
Appena è stata effettuata "la cattura", viene settato il bit di flag interrupt CCP1IF in PIR1.

Nella modalità COMPARE, il valore del registro CCPR1, a 16 bit, viene continuamente confrontato col valore del timer TMR1; quando i due valori sono uguali viene generato un evento sul piedino CCP1.
Questo evento può essere:

pin CCP1 posto alto
pin CCP1 posto basso
pin CCP1 invariato.

Contemporaneamente viene settato anche il bit di flag interrupt CCP1IF in PIR1.

program prova_Int_12
' 16F877A - 8MHz

sub procedure interrupt
    if testbit(PIR1,SSPIF) then
        ..... vostre istruzioni
        clearbit(PIR1,SSPIF)
    end if
end sub

main:
    setbit(PIE1,SSPIE)   'abil. interr. SSP
    setbit(INTCON,PEIE) 'abil. interr. perif.
    setbit(INTCON,GIE)  'abil. tutti interrupt

    while TRUE
        ..... vostre istruzioni
    wend
end.

Interrupt della Porta Seriale Sincrona (SSP)

.

program prova_Int_9
' 16F877A - 8MHz

sub procedure interrupt
    if testbit(PIR1,TXIF) then
        ..... vostre istruzioni
    end if
end sub

main:
    setbit(PIE1,TXIE)   'abil. interr. TX USART
    setbit(INTCON,PEIE) 'abil. interr. perif.
    setbit(INTCON,GIE)  'abil. tutti interrupt

    while TRUE
        ..... vostre istruzioni
    wend
end.

Interrupt su trasmissione USART

Il bit TXIF indica lo stato del registro TXREG.

Il Transmit Shift Register (TSR) prende i dati dal Transmit Buffer Register (TXREG), a sua volta caricato via software.

Il registro TSR non viene caricato finchè non è stato trasmesso l'ultimo bit del dato precedente; non appena questo avviene, il TSR viene riempito con un nuovo dato dal TXREG in un ciclo istruzione.

TXREG rimane, allora, vuoto e ciò provoca il settaggio del bit di flag interrupt TXIF di PIR1, senza tener conto dello stato del bit di abilitazione TXIE.

TXIF sarà azzerato al caricamento di un nuovo dato in TXREG.

program prova_Int_10
' 16F877A - 8MHz

sub procedure interrupt
    if testbit(PIR1,RCIF) then
        ..... vostre istruzioni
    end if
end sub

main:
    setbit(PIE1,RCIE)   'abil. interr. RX USART
    setbit(INTCON,PEIE) 'abil. interr. perif.
    setbit(INTCON,GIE)  'abil. tutti interrupt

    while TRUE
        ..... vostre istruzioni
    wend
end.

Interrupt su ricezione USART

Dopo la ricezione dell'ultimo bit, il dato viene trasferito dal Receive Shift Register (RSR) al registro RCREG e, quando il trasferimento è completo, viene settato il flag di interrupt RCIF di PIR1, che è un bit a sola lettura, azzerato dall'hardware quando RCREG è stato letto ed è vuoto.

Il bit di flag RCIF sarà settato quando la ricezione è completa ed un interrupt sarà generato se il bit RCIE in PIE1 è stato settato.

program prova_Int_13
' 16F877A - 8MHz

sub procedure interrupt
    if testbit(PIR1,ADIF) then
        ..... vostre istruzioni
        clearbit(PIR1,ADIF)
    end if
end sub

main:
    setbit(PIE1,ADIE)   'abil. interr. conv. A/D
    setbit(INTCON,PEIE) 'abil. interr. perif.
    setbit(INTCON,GIE)  'abil. tutti interrupt

    while TRUE
        ..... vostre istruzioni
    wend
end.

Interrupt su completamento conversione A/D

Quando la conversione A/D è stata completata, viene generato un'interrupt settando il bit di flag ADIF di PIR1.

program prova_Int_15
' 16F877A - 8MHz

sub procedure interrupt
    if testbit(PIR1,PSPIF) then
        ..... vostre istruzioni
        clearbit(PIR1,PSPIF)
    end if
end sub

main:
    setbit(PIE1,PSPIE)  'abil. interr. PSP
    setbit(INTCON,PEIE) 'abil. interr. perif.
    setbit(INTCON,GIE)  'abil. tutti interrupt

    while TRUE
        ..... vostre istruzioni
    wend
end.

Interrupt su lettura/scrittura PSP

.

program prova_Int_16
' 16F877A - 8MHz

sub procedure interrupt
    if testbit(PIR2,CCP2IF) then
        ..... vostre istruzioni
        clearbit(PIR2,CCP2IF)
    end if
end sub

main:
    setbit(PIE2,CCP2IE) 'abil. interr. CCP2
    setbit(INTCON,PEIE) 'abil. interr. perif.
    setbit(INTCON,GIE)  'abil. tutti interrupt

    while TRUE
        ..... vostre istruzioni
    wend
end.

Interr. del modulo Capture/compare (CCP2)

Nella modalità CAPTURE, i registri CCPR2L e CCPR2H "catturano" il valore a 16 bit del timer TMR1 quando si verifica un determinato evento sul piedino CCP2.
Questo evento può essere:

un fronte di salita o di discesa
ogni 4 fronti di salita
ogni 16 fronti di discesa.

La modalità dell'evento viene determinata attraverso un registro di configurazione.
Appena è stata effettuata "la cattura", viene settato il bit di flag interrupt CCP2IF in PIR2.

Nella modalità COMPARE, il valore del registro CCPR2, a 16 bit, viene continuamente confrontato col valore del timer TMR1; quando i due valori sono uguali viene generato un evento sul piedino CCP2.
Questo evento può essere:

pin CCP2 posto alto
pin CCP2 posto basso
pin CCP2 invariato.

Contemporaneamente viene settato anche il bit di flag interrupt CCP2IF in PIR2.

program prova_Int_17
' 16F877A - 8MHz

sub procedure interrupt
    if testbit(PIR2,BCLIF) then
        ..... vostre istruzioni
        clearbit(PIR2,BCLIF)
    end if
end sub

main:
    setbit(PIE2,BCLIE)  'abil. int. collis. bus
    setbit(INTCON,PEIE) 'abil. interr. perif.
    setbit(INTCON,GIE)  'abil. tutti interrupt

    while TRUE
        ..... vostre istruzioni
    wend
end.

Interrupt su collisione bus SSP

.

program prova_Int_5
' 16F877A - 8MHz

dim conta, scrivi as byte

sub procedure interrupt
    if testbit(INTCON,RBIF) then
        if testbit(PORTB,7) then
            scrivi = 1
        end if
        clearbit(INTCON,RBIF)
    else
        if testbit(INTCON,INTF) then  'portb.0
            if testbit(PORTB,2) then
                clearbit(PORTB,2)
            else
                setbit(PORTB,2)
            end if
            clearbit(PORTB,3)
            clearbit(INTCON,INTF)
        else
            if testbit(INTCON,TMR0IF) then  'TMR0
                Inc(conta)
                TMR0 = 100
                clearbit(INTCON,TMR0IF)
            else                       'EEprom int
                if testbit(PIR2,EEIF) then
                    setbit(PORTB,3)
                    clearbit(PIR2,EEIF)
                end if
            end if
        end if
    end if
end sub

main:
    PORTA = 0
    ADCON1 = %00000110      'portA digitale
    TRISA = %00000
    PORTB = 0
    TRISB = %10000001
    OPTION_REG = %11000101 'prescaler 1:64
    TMR0 = 100
    conta = 0
    scrivi = 0
    setbit(INTCON,RBIE) 'abil. int. portb.7
    setbit(INTCON,INTE) 'abil. interr. portb.0
    setbit(INTCON,TMR0IE) 'abil. interr. TMR0
    setbit(PIE2,EEIE)   'abil. interr. EEprom
    setbit(INTCON,PEIE) 'abil. interr. perif.
    setbit(INTCON,GIE)  'abil. tutti interrupt

    while TRUE
        if conta = 200 then
            PORTA = not PORTA
            conta = 0
        end if
        if scrivi = 1 then
            Eeprom_Write(2, 10)
            scrivi = 0
        end if
    wend
end.

Ciclo completo di scrittura su Eeprom

Viene generato un'interrupt settando il bit di flag EEIF di PIR2, appena un programma termina un ciclo normale di memorizzazione su Eeprom.

Dopo l'etichetta main, impostiamo PORTA come uscita, PORTB.0 e PORTB.7 come ingressi, il resto come uscite.

Impostiamo a 1 i bit RBIE, INTE, TMR0IE di INTCON per abilitare gli interrupt visti più sopra.
Impostiamo a 1 anche il bit EEIE di PIE2, abilitando le interruzioni sulla scrittura completata in EEprom.

Impostiamo a 1 anche i bit PEIE e GIE di INTCON per abilitare tutti gli interrupt.

Tutta PORTA sarà impostata a 0. Ogni volta che la variabile conta arriverà a 200, PORTA verrà invertito di stato.
Il risultato sarà che PORTA lampeggerà con cadenza di circa 1 secondo.

Se la variabile scrivi è uguale a 1, si effettuerà la scrittura di un dato in EEprom.

A questo punto, quando verrà generato un'interruzione qualunque, il programma interromperà l'esecuzione e salterà all'indirizzo del vettore di interrupt dove c'è la sub procedura interrupt ed eseguirà il test del bit RBIF di INTCON.
Se questo bit sarà a 1, si eseguirà il test del bit 7 di PORTB.
Se questo bit sarà a 1, viene impostata a 1 la variabile scrivi, che permetterà la scrittura di un dato in EEprom.
Prima di uscire, azzeriamo il bit RBIF di INTCON.

Oppure eseguirà il test del bit INTF di INTCON.
Se questo bit sarà a 1, si accenderà o spegnerà il LED su PORTB.2.
Si spegnerà anche il LED su PORTB.3, acceso dalla gestione interrupt su scrittura EEprom.
Prima di uscire, azzeriamo il bit INTF di INTCON.

Oppure eseguirà il test del bit TMR0IF di INTCON.
Se questo bit sarà a 1, si eseguiranno le istruzioni predisposte per gestire il Timer0.
Prima di uscire, mettiamo a 0 il bit TMR0IF di INTCON.

Oppure eseguirà il test del bit EEIF di PIR2.
Se questo bit sarà a 1, significa che l'interrupt è stato generato dalla scrittura completata in EEprom e quindi, verrà acceso il LED su PORTB.3.
Prima di uscire, azzeriamo il bit EEIF di PIR2.

Ora, il programma uscirà dalla sub e riprenderà l'esecuzione da dove era stata interrotta precedentemente.

program prova_Int_11
' 16F877A - 8MHz

sub procedure interrupt
    if testbit(PIR2,CMIF) then
        ..... vostre istruzioni
        clearbit(PIR2,CMIF)
    end if
end sub

main:
    setbit(PIE2,CMIE)   'abil. interr. compar.
    setbit(INTCON,PEIE) 'abil. interr. perif.
    setbit(INTCON,GIE)  'abil. tutti interrupt

    while TRUE
        ..... vostre istruzioni
    wend
end.

Interrupt su cambio stato dei comparatori

Quando lo stato di uscita di uno dei due comparatori cambia, viene generato un'interrupt settando il bit di flag CMIF di PIR2, in risposta al quale è necessario, via software, andare a leggere i due bit C1OUT e C2OUT di CMCON per sapere quale dei due comparatori ha realmente cambiato stato.

 

  •     Sorgenti mikroBasic per questi appunti

Bibliografia:
Manuale mikroBasic
PICmicro MID-RANGE MCU family - section 8. Interrupts
PIC18C Reference Manual - section 10. Interrupts
Datasheet PIC16F877A

Continua nella successiva parte

Ultima modifica  

 
Privacy Policy Cookie Policy