• Non ci sono risultati.

Comunicazione con dispositivi esterni

CPL P3.0 RETI

Prima di tutto va notato che l'istruzione CLR TF0 e' sparita. Questo perché, quando l'8051 esegue la routine dell'interrupt del timer 0, cancella automaticamente il flag TF0. Inoltre invece della normale istruzione RET si è usato l'istruzione RETI. Quest' ultima fa le stesse cose della precedente ma informa l'8051 che la routine di interrupt è finita.

Bisogna sempre terminare un interrupt handler con RETI.

Tornando all'esempio precedente, ogni 65536 cicli d'istruzione eseguiremo le istruzioni CPL e RETI che

richiedono solo 3 cicli. Come risultato finale il nostro codice è 437 volte più efficiente del precedente senza contare che è più facile da leggere e da capire. Bisogna solo predisporre l'interrupt e dimenticarsi, fiduciosi che l'8051 eseguirà il codice quando serve.

Lo stesso concetto si applica alla ricezione dei dati dalla porta seriale. Una possibilità è quella di controllare continuamente lo stato del flag RI in un loop infinito. Oppure si potrebbe controllare il flag all'interno del più grande loop del programma principale. Nel peggiore dei casi si potrebbe correre il rischio di perdere il carattere ricevuto. Se un carattere viene ricevuto subito dopo che e' stato effettuato il controllo del flag RI, nella prosecuzione del resto del programma, prima di controllare di nuovo RI, un nuovo carattere potrebbe arrivare e si sarebbe perso il precedente.

Usando l'interrupt, l'8051 ferma il programma e richiama l'interrupt handler per servire la ricezione del carattere. Così non si sarà costretti a scrivere un antiestetico controllo nel codice e nemmeno correre il rischio di perdere i caratteri ricevuti.

Quali sono gli eventi possono attivare un interrupt.

Possiamo configurare l'8051 affinché ognuno di questi eventi possa causare un interrupt:

Overflow del Timer 0 Overflow del Timer 1

Ricezione/trasmissione di un carattere dalla seriale Evento esterno 0 (INT 0).

Evento esterno 1 (INT 1).

Ovviamente è necessario poter distinguere tra vari interrupt ed eseguire dei codici differenti per ognuno di

loro. Quando l'interrupt viene attivato, il microcontrollore salterà a degli indirizzi di memoria predefiniti come mostrato nella fig.3.11 che segue:

40 Interrupt Flag Indirizzo dell’interrup handler

INT 0 IE0 0003h

Timer 0 TF0 000Bh

INT 1 IE1 0013h

Timer 1 TF1 001Bh

Seriale RI/TI 0023H

Fig.3.11

Se si consulta la tabella, si può affermare che, se il timer 0 va in overflow, il programma principale sospenderà momentaneamente il programma e salterà all'indirizzo 000Bh dove si dovrà scrivere l'interrupt handler opportuno.

 Configurare gli interrupt

Al power up, per default, tutti gli interrupt sono disabilitati, questo significa che, anche se per esempio il flag TF0 è attivo, l'interrupt non verrà accettato.

Il programma deve specificatamente dire all'8051 che

intende abilitare la gestione degli interrupt e indicare quali interrupt sono abilitati ad essere serviti.

Il programma può abilitare o disabilitare gli interrupt mediante il registro IE (A8h):

REGISTRO IE (A8h)

Bit Nome Indirizzo Bit Funzione dell’interrupt Handler

7 EA AFh Abilita globalmente gli interrupt

6 - AEh Non definito

5 - ADh Non definito

4 ES ACh Abilita l’interrupt della seriale

3 ET1 ABh Abilita l’interrupt del Timer 1

2 EX1 AAH Abilita l’interrupt esterno INT1

1 ET0 A9h Abilita l’interrupt del Timer 0

0 EX0 A8h Abilita l’interrupt esterno INT1

Fig.3.12

41 Come si può notare, ciascun interrupt dell'8051 dispone si un suo bit nel registro IE. Si può abilitare un

determinato interrupt, settando il corrispondente bit. Per esempio, se si deve abilitare l'interrupt del Timer

1, si possono usare ambedue le seguenti istruzioni:

MOV IE,#08h Oppure

SETB ET1

Ambedue le istruzioni settano il bit 3 di IE, e abilitano l'interrupt del Timer 1. Affinché l'interrupt del Timer 1

(e questo vale anche per gli altri) sia effettivamente abilitato, è necessario settare anche il bit 7 di IE (Attivazione degli interrupt globale), se tale

bit rimane a zero, nessun interrupt anche abilitato sarà attivo. Porre ad uno il bit 7 di IE abilita globalmente

tutti gli interrupt i cui bit sono allo stato on.

Questo bit è utile durante l'esecuzione di un programma che abbia una porzione di codice con criticità

temporali. Allora, per evitare che quella parte di codice possa essere interrotta da un qualsiasi interrupt, sarà

sufficiente resettare il bit 7 di IE e settarlo di nuovo quando la sezione critica è terminata.

Sequenza di Polling

Durante ogni istruzione, l'8051 verifica che non vi sia un interrupt da servire. Durante tale controllo, esso

Questo significa che, se sul'interrupt della seriale si attiva nello stesso momento quello esterno INT 0,

quest'ultimo verrà servito per primo e quello relativo alla porta seriale immediatamente dopo.

42 Priorita' degli Interrupt

L'8051 dispone di due livelli di priorità degli interrupt: alto e basso. Usando tali priorità potete cambiare

l'ordine con il quale gli interrupt vengono serviti.

Per esempio, se si ha abilitato sia l'interrupt del Timer 1 che quello della porta seriale e si ritiene che la

ricezione di un carattere sia molto più importante della gestione del timer, si può assegnare alla seriale un

priorità alta, in maniera da cambiare l'ordine standard con il quale il micro serve normalmente gli interrupt.

La priorità degli interrupt è controllata dal registro IP (B8h).

Esso ha il seguente formato:

Bit Nome Indirizzo Bit Funzione

7 - - Non definito

6 - - Non definito

5 - - Non definito

4 PS BCh Priorità Interrupt Seriale

3 PT1 BBh Priorità Interrupt Timer1

2 PX1 BAh Priorità Interrupt esterni INT1

1 PT0 B9h Priorità Interrupt Timer0

0 PX0 B8h Priorità Interrupt esterni INT0

Fig.3.13

Quando consideriamo la priorità degli interrupt, vanno applicate le seguenti regole:

 Nulla può interrompere un interrupt ad alta priorità, nemmeno un altro dello stesso tipo.

 Un interrupt ad alta priorità può invece interromperne uno a bassa priorità.

 Un interrupt a bassa priorità può essere iniziato soltanto quando nessun altro interrupt è

43 Cosa succede quanto si verifica una richiesta d'interrupt?

Al momento che un interrupt viene richiesto, il microcontrollore automaticamente esegue le seguenti

operazioni:

 Il valore del Program Counter viene salvato nello stack, a partire dal byte meno significativo.

 Tutti gli interrupt della medesima o più bassa priorità sono bloccati.

 Se l'interrupt riguarda o un timer o una richiesta esterna, viene disattivato il flag corrispondente.

 L'esecuzione del programma salta all'indirizzo dell'interrupt handler corrispondente.

Una speciale attenzione è richiesta circa il terzo passo nel quale il flag viene automaticamente cancellato.

Ciò significa che non è necessario farlo all'interno del codice.

Che succede quando un interrupt finisce?

Un interrupt termina quando viene eseguita l'istruzione RETI (Return from Interrupt). A quel punto il

microcontrollore esegue i seguenti passi:

 Due byte vengono prelevati dallo stack (operazione di pop) e messi nel Program Counter per tornare al

programma principale.

 Lo stato dell' interrupt è rimesso nella condizione precedente all'inizio dell'interrupt stesso.

Interrupt seriali

Gli interrupt seriali sono leggermente diversi da tutti gli altri. Ciò è dovuto al fatto che ci sono due flag di interrupt: RI e TI. Se uno dei due è attivo allora anche l'interrupt della seriale diventerà attivo. Questo vuol

dire che, al momento di una richiesta di interrupt sulla seriale, non si conosce quali dei due o tutti e due i

flag sono attivi. Allora, l'interrupt handler deve verificare lo stato dei flag e comportarsi di conseguenza. Inoltre deve anche cancellare i flag poiché l'8051 volutamente non lo fa in maniera automatica.

Es.:

44

MOV SBUF,#?A? ; Copia il nuovo carattere da inviare nel buffer di trasmissione.

Documenti correlati