Loading
Note di Apprendimento
Study Reminders
Support
Text Version

Interruzioni in MSP430 Roundup

Set your study reminders

We will email you at these times to remind you to study.
  • Monday

    -

    7am

    +

    Tuesday

    -

    7am

    +

    Wednesday

    -

    7am

    +

    Thursday

    -

    7am

    +

    Friday

    -

    7am

    +

    Saturday

    -

    7am

    +

    Sunday

    -

    7am

    +

Introduzione a Embedded System Design Dhananjay V. Gadre (NSUT, New Delhi) &
Badri Subudhi (IIT, Jammu) Indian Institute of Technology, Delhi Module 8 Lecture 26 Interrupts in MSP430 - Continuo (Riferirsi Slide Time: 00.38) Riprendiamo la nostra discussione sugli interrupt che abbiamo avuto, in questa sessione di oggi.
Ora, fatemi anche citare un po' di più su questi interruzioni. Come abbiamo visto, le interruzioni possono essere classificate come interruzioni maschilabili o non maschilabili. Abbiamo visto che sul nostro MSP430 abbiamo entrambe le varietà.
C'è un altro modo per classificare le interruzioni e che si occupa di vectored e non - vectored. Qual è il significato? Quando uso il termine interrompe i vettori, questo significa che ogni volta che succede un'interruzione, so esattamente dove andare a cercare la subroutine per affrontare quell' interruzione. Posso anche avere interruzioni non vettorate che significa bene, è accaduto un'interruzione ma esattamente non so dove andare e quindi il sistema deve fornirmi alcune informazioni per aiutarmi a localizzare la subroutine per gestire questa interruzione non - vectorata.
Ebbene, MSP430, la maggior parte delle interruzioni sono interruzioni di tipo vectorato, tutte le interruzioni sono interrotte da vettori. La fonte dell'interruzione fornisce anche l'indirizzo. Infatti questo indirizzo è disponibile nella mappa della memoria di MSP430. La parte superiore, cioè le posizioni di memoria più alte sono riservate ai vettori di memorizzazione per ciascuna delle fonti di interruzione. Inoltre, ora immaginate che in un dato momento, quando il microcontrollore è pronto a, si sa, diradarsi per aver eseguito una subroutine di interruzione, cosa se accadde due interruzioni contemporaneamente? Ovviamente il microcontrollore non può andare a soddisfare le esigenze di entrambe le fonti di interruzione contemporaneamente, quindi deve privilegiare.
(Riferimento Slide Time: 02.44)
E questo si chiama, qual è la priorità di interruzione - che significa quella con, se accadono due eventi, quello con priorità più alta sarà servito per primo. Dopo il completamento di quell' interruzione, è possibile andare ed eseguire una sottoroutine per la seconda interruzione.
Il vettore di reset, e vediamo come questo viene prioritizzato in MSP430. L'indirizzo vettoriale più alto significa una priorità più elevata. E quindi il vettore reset ha priorità più alta, perché? Poiché si trova a questo indirizzo e giusto per ripetere, l'indirizzo è un due indirizzi che è la tua istruzione è a FFFE e FFFF, ok? Così si va, quindi il vettore a questo indirizzo avrà la massima priorità. Quello dopo che sarà FFFC e FFFD sarebbe l'interruzione di priorità più bassa rispetto a questo e così via. (Vedi Slide Time: 03.45) Ecco il clipping dal foglio di dati MSP430 che elenca tutti gli interruzioni - quali sono i loro nomi, la fonte e qual è la bandiera riferita alla bandiera di interruzione che abbiamo citato e qual è l'indirizzo del vettore per quell' interruzione e qual è la priorità. Ovviamente, come ho accennato ' 31, la priorità più alta è per il reset e mentre si scende, la priorità diminuisce il che significa che è accaduto due interruzioni, quella con la priorità più alta sarà servita prima.
E come si vede, noi, le fonti di interruzione sono - condizione di accensione, reimpostazione esterna - ovvero un utente che preme il pulsante di reset o di interruzione non maschilabile o un timer qui - comparatori, timer watchdog. Un altro timer - i protocolli di comunicazione seriale, l'ADC e last but not the least, i due porti che abbiamo su MSP430 G 2553.
Infatti, ricorderete che MSP430 G2553 è effettivamente disponibile in diverse impronte fisiche. Quello che abbiamo sulla nostra scatola del pranzo è in formato dip; ha due porte. Ma se il MSP430 è scelto per essere della versione SMD, ha tre porte. Porta 1, Porta 2 e Porta 3. Ma, la porta 3 non ha alcuna capacità di interruzione. L'unica possibilità di interruzione che hai per questo numero di microcontrollore è per la porta 1 e la porta 2. E come vedi, la porta 1 ha la priorità più bassa in questo e anche qui si vedono queste sono tutte le interruzioni maschilabili e solo l'interruzione NMI è non maschilabile. Procediamo dunque a further.Now, come ho accennato, una bandiera interrotta è un elemento importante in tutto il processo di interruzione che viene generata, essendo riconosciuta ed essendo servita. E il flag di interruzione, una volta generato, verrà automaticamente vettore in una posizione di indirizzo e di solito avrà una sola sorgente. Ma ci sono periferie dove un singolo vettore vi aiuterà a generare fonti da diversi piedini.
(Riferimento Slide Time: 06.19) Ad esempio porta 1 o porta 2 - ognuna di queste porte come si sa ha 8 pin e ognuno dei 8 pin può generare un'interruzione. Ma se il pin si riferisce alla porta 1, tutti i 8 pin avranno un singolo vettore.
Quindi ti porterà nella stessa posizione e dovrà eseguire la stessa subroutine in quella località. In quella subroutine dovrete individuare quale fosse, di tutti i 8 pin, che ha causato l'interruzione, giusto? Quindi ci occuperemo di questo.
Quindi quando si è quando si è pronti incorporare interruzioni nel proprio sistema, nella programmazione, nel sistema incorporato, ci sono alcune cose che bisogna tenere a mente.
È necessario mantenere la subroutine di interruzione molto breve. E uno dei modi per garantire che non si utilizzi alcuna subroutine di ritardo nella funzione di interruzione, nella subroutine di interruzione - perché?
Quando ci si prende troppo tempo in quella subroutine di interruzione, quello che sta facendo è - si sta vincolando il resto dell'esecuzione del programma principale o si sta morendo di fame altre fonti di interruzioni. Vuoi dare a tutte le fonti di interrompere una giusta occasione, una partecipazione equa, quindi mustete la routine del servizio di interruzione molto breve. Ora, e se vuoi davvero eseguire un programma più grande? Il modo per affrontare il problema è quello di interagire, affrontare il requisito nel programma principale, non nella subroutine di interruzione.
Quando si esegue una subroutine di interruzione, per impostazione predefinita tutte le altre interruzioni maschilabili sono disabilitate - questo è il significato. Pertanto, è necessario mantenere l'esecuzione della subroutine di interruzione corrente ad una lunghezza di programma più breve possibile in modo da poterla terminare rapidamente. Quando si torna indietro, si abiliteranno gli interruzioni, in modo che altre fonti di interruzione potessero avere una possibilità.
Ora, per l'interruzione da accettare, ci sono diverse condizioni che devono essere soddisfatte. La prima è che perché le interruzioni sono spesso generate da fonti esterne, il che significa che sono asincrone all'esecuzione della corrente, il programma sul microcontrollore, non significa che il momento in cui si genera un'interruzione, il microcontrollore sospenderà qualunque cosa stia facendo e si affretterà ad eseguire la subroutine per quell' interruzione.
(Riferimento Slide Time: 08.53) La stessa, al minimo, completerà il programma corrente, l'istruzione corrente, se ha iniziato a feticarlo che lo completerà. E come si sa, la lunghezza di queste istruzioni prende un ciclo di clock o potrebbe scattare 6 cicli di clock. Quindi se nel primo ciclo di clock, un evento di interruzione che accade, dovrà attendere i 6 cicli di clock associati all'istruzione corrente vengono completati. Inoltre, una volta che l'interruzione viene riconosciuta, se non ci fosse stato l'interruzione, il microcontrollore sarebbe passato alla successiva posizione per recuperare l'istruzione successiva ed eseguirla. Ma ora perché l'interruzione è avvenuta, deve memorizzare il valore del contatore del programma da qualche parte e questo da qualche parte è, la posizione è un percorso di memoria nella RAM e chiamiamo questa location di memoria, regione speciale in quella RAM, la chiamiamo 'stack'.
E così il microcontrollore salva il valore del contatore del programma sulla pila. Poi a parte il contatore del programma, lo stato del microcontrollore si riflette nel registro di stato. Anche questo viene salvato sulla pila. Così che quando riprendi il tuo programma interrotto, puoi riprendere con lo stato che avevi prima dell'interruzione.
Ora, se sono accadute più interruzioni, si privilegierebbe e darebbe la massima priorità alla massima priorità, priorità più elevata interrompere ed eseguire un'istruzione - subroutine relative a quell' interruzione. L'indicatore di interruzione si reimposta automaticamente su bandiere di origine singola, cioè se ci sarà una fonte di interruzione che non è condivisa con altre risorse, il momento in cui l'interruzione viene riconosciuta, reimposterà questa bandiera, in modo che la prossima volta che un altro evento accada su quella risorsa, potrà essere catturato.
Inoltre, cancella il registro di stato all'interno della subroutine di interruzione. Quindi quando si entra nella sottoroutine di interruzione, il registro di stato riflette, riflettendo dal programma principale viene salvato sulla pila e all'interno della subroutine di interruzione, si ottiene un registro di stato pulito tutti i bit vengono reimpostati a 0 e questo permetterà di uscire effettivamente dalle modalità di bassa potenza. Il GI, cioè il bit Global Interrupt che è come l'interruttore globale è anche sdoganato e ulteriori interruzioni sono disabilitate - il che significa quando ci si trova in una subroutine di interruzione, se dovesse accadere qualsiasi altra interruzione, si dovrà aspettare.
Una volta che queste condizioni sono tutte soddisfatte, poi prima di entrare nella subroutine il vettore di interruzione viene caricato sul contatore del programma e da lì, il microcontrollore avvia il caricamento e l'esecuzione delle istruzioni di quella subroutine. (Fare Slide Time: 11.53) Per aiutare tornare al programma principale, quindi questo è il tuo, questo è un riflesso di quello che sarà lo stato della RAM. Quindi diciamo, prima che l'interruzione sia avvenuta, il micro, il puntatore dello stack puntava a questo indirizzo e ogni volta che l'interruzione avviene, deve memorizzare due contenuti, due parole uno è il contatore del programma e l'altro è il registro di stato. Così ora TOS spicca per la cima della pila. Quindi quello che era in cima alla pila qui è ora in questa posizione quattro posizioni di memoria sono utilizzate per memorizzare i, questi per registrarsi; il contatore del programma e il registro di stato. (Fare Slide Time: 12.42) Ora, una volta che ci si trova all'interno della subroutine di interruzione e si è eseguito il programma, si farebbero le stesse cose che ha fatto mentre si entra nella subroutine di interruzione nell'ordine inverso. Il registro di stato dell'impostazione precedente verrà poppato dalla pila che significa quando si era, quando si era interrotto, quando era stato interrotto nel programma principale, il registro di stato è stato salvato sulla pila che verrà recuperato.
E il contatore del programma viene recuperato anche dallo stack, quel valore, inserito nel registro del programma in modo da poter riprendere l'esecuzione del programma che si è interrotto, che è stato sospeso - che chiamiamo come il programma principale, quindi questo viene mostrato qui. Ora, per la gestione delle interruzioni, ai fini dell'illustrazione qui, utilizzeremo i pin di output in ingresso. E così analizzeremo tutti i registri che aiutano a manipolare, che aiutano il controllo o che aiutano, insomma, a gestire tutte le interruzioni associate al GPIO; i pin di output di input generali. E abbiamo tre registri che ci aiutano a gestire gli interruzioni associati ai pin di output in ingresso. (Fare Slide Time: 14.06) Tutti questi registri sono di 8 bit larghezza. Abbiamo un registro delle abilitazioni per il registro delle abilitazioni PXIE; X qui si fa riferimento a quale porta di cui stiamo parlando. Ad esempio, se si parla di porta 1, quel registro sarà P1IE. Abbiamo un registro di selezione dei margini di interruzione, perché? Poiché si potrebbe generare un'interruzione sul bordo in salita di un segnale su un pin di porta, si potrebbe anche generare un'interruzione sul bordo in caduta.
Quindi devi dire al microcontrollore, vuoi essere interrotto quando il segnale va così o vuoi essere interrotto quando il segnale va così. Così che viene indicato al microcontrollore scrivendo valori appropriati in questo registro chiamato registro di selezione dei margini di interruzione. E il terzo, il registro più importante è il registro delle bandiere di interruzione e per riferimento, ho replicato quel diagramma di blocco precedente di interruzioni, in modo da poter assegnare o localizzare questi registri in questo diagramma di blocco.
Così il programma di interruzione del programma di interruzione è questa parte, qui, qui. Quindi, se si desidera che una particolare interruzione sia abilitata, è necessario abilitarla in questo registro. Così colpisce questa parte rossa. La selezione edge e la cassa di bandiera insieme sono qui e quindi bisogna ottenere un 1 in questo bit blu, se quello è 1, e questo interruttore che è rappresentato da quel cerchio rosso, se quell' interruttore è chiuso, allora solo si genererebbe un interruttore, come ha fornito questo interruttore padronale, che lo colorate in un interruttore master di terzo colore qui, è anche acceso. E questo può essere abilitato in vari modi, può anche essere disabilitato e vedremo due metodi di controllo di questa bandiera in un programma successivamente. Quindi per ribadire abbiamo tre registri che dobbiamo manipolare in modo da gestire le interruzioni sui pin di output in ingresso di microcontrollore MSP430. Procediamo avanti.
(Riferimento Slide Time: 16.42) Ora, P1IE. cioè porta 1, se voglio parlare di porta 1, interrompere l'abilitazione. Questo è un registro di 8 bit corrispondente ai 8 pin che si ha per la porta 1. Se si desidera abilitare l'interruzione su uno qualsiasi dei piedini, è necessario scrivere 0, è necessario scrivere 1 in quel bit. Quindi lasciatemi dire, disegnate qui i 8. Quindi questo sarebbe il tuo P1IE, questo è un po' 0, questo è un po' 7. Se scrivo un 1 qui, questo significa che voglio interrompere associato alla porta P1.0 1 bit 0, per essere abilitato.
Ovviamente un segnale deve essere applicato alla porta 1 bit 0 per l'interruzione in realtà, ma questo lo si sta abilitando. E se vuoi disabilitarlo, scrivi un 0. Quindi se scrivo 0 nel resto, questo significa che non voglio essere interrotto da alcun segnale su uno qualsiasi dei piedini della porta 1 tranne il bit 0. Questa è l'interpretazione del registro di interruzione della porta 1. (Fare Slide Time: 18.00) Secondo in linea è il registro di selezione dei margini di interruzione. Come ho accennato, si può generare un'interruzione sul bordo in salita e si può generare un'interruzione sul bordo in caduta. Devi dire al micro controller che edge ti piacerebbe generare un'interruzione e di nuovo qui, ci sono 8. E qui scrivo il nome del registro che questa è P1 IES, interruzione selezione edge.
Se scrivo un 1 qui, questo significa che genererà un'interruzione quando c'è una transizione dall'alto al basso; quindi 1 significa alto a basso. Quindi un bordo in caduta genererà un'interruzione se hai scritto un 1 in quel corrispondente evento. Se scrivi 0, questo significa che vuoi un'interruzione nel bordo dell'alzata.
Quindi a seconda del tuo requisito, a seconda dello stato della logica su quel particolare pin, puoi scrivere un 1 o un 0. Il bit corrispondente nel registro precedente interrompere il registro deve essere 1, altrimenti scrivere un 1 o 0 qui non ha alcun senso. (Fare Slide Time: 19.20)
E il terzo è il registro delle bandiere di interruzione. Questo registro di bandiera quando, se diventa 1, che diventerà 1 su quale condizione? Che sia stato abilitato il registro e un segnale esterno qualificato dal registro di selezione edge è stato ricevuto, poi e poi solo, un determinato bit in questo registro sarà impostato a 1. E se quel bit è fissato a 1, soggetto ad altre condizioni che si incontreranno, porterà a un interruzione.
Lasciate che lo mostri di nuovo qui. Quindi si tratta di P1IFG, se questo bit è 1, questo significa che un'interruzione sulla porta 1 bit 0 è stata riconosciuta e se il bit di interruzione globale è abilitato, questo volerà; interromperà la CPU e la CPU andrà al vettore di interruzione associato alla porta 1 e da lì eseguirà la subroutine e potrai fare quello che vuoi all'interno di quella subroutine.
Questo è il senso di questo. Ovviamente questi bit possono anche essere impostati o reimpostati in, per software, scrivendo un 1 o 0 e questo genererà un interrotto software controllato che è il significato.
Normalmente non si vuole farlo, ma questo è anche possibile.
Vediamo quindi qual è il flusso del programma quando ci occupiamo di interruzioni, questo è molto importante. Ora in C, come si fa a raccontare il programma, quando si sta scrivendo un programma in linguaggio C, come si fa a dire al compilatore che questa subroutine a cui si sta scrivendo è a, allo scopo di gestire una particolare interruzione. (Fare Slide Time: 21.12)
E lo si fa utilizzando una dichiarazione # chiamata #pragma. Questo è un vettore di parole chiave. Stai dicendo che ti occuperai di un timer 0, un vettore di 0 e quale programma eseguire in risposta a questo vettore? Questo è il nome del programma. Quindi tu, questo è per via, doppio questo, interrompere questi vuoti questi sono tutti necessari, non puoi cambiare questi. Questa, è la tua scelta, questo nome è la tua scelta; puoi mettere il tuo nome.
Quindi devi avere un #pragma, nome dato. Allora questa è una parola chiave qui e il nome stesso il nome della subroutine è la tua scelta, puoi mettere qualunque cosa tu voglia, ovviamente non dovrebbe essere una parola chiave riservata o altro che questo sia richiesto. Una volta che scrivi questo nel tuo programma C, devi quindi, lì dopo aver scritto questa subroutine associata a questa etichetta. Ora vuoto qui significa che non stai passando alcun parametro alla subroutine né ti sta causando alcun risultato. Allora come ti aiuta un programma di interruzione? Attraverso il modo di disattivare le posizioni di memoria condivise, ok? Variabili. Così vedremo come è gestito.
Ora ho messo insieme questa lista dal file di intestazione MSP430 in modo che sappiate quali sono i nomi per ognuno dei vettori; come per il timer 0, cosa è il vettore e così via. (Fare Slide Time: 22.55) Qui c'è il, come potete vedere, questo è il vettore per la trappola, ovvero l'interruzione non maschilabile. No, questo non è l'interruzione non maschilabile, dovrebbe arrivare da qualche parte. Quindi questo è un vettore trap.
Poi hai il vettore di porta 1, cioè il vettore che ti faresti quando c'è un'interruzione sulla porta 1. Qui è per la porta 2 e così via. Quindi nel tuo programma C è necessario utilizzare questi nomi esatti in maiuscolo per, per consentire di collegare la subroutine di interruzione per quella particolare periferica. Lo illustreremo con un esempio. (Vedi Slide Time: 23.41) Ora cosa fai, cosa succede in una subroutine di interruzione? Beh il momento in cui il programma principale è interrotto, devi salvare il contesto, e cosa intendo per il contesto? Il contesto si riflette da due cose il registro di stato più il contatore del programma. Quindi entrambi questi registri devono essere salvati in modo da poter riprendere a usare i valori qui qualunque programma sia stato interrotto.
Quindi questo deve essere salvato e questo viene fatto automaticamente dal microcontrollore, come? Si salva questi due registri sulla pila. Ora una volta inserito una subroutine di interruzione, il bit di interruzione globale è disattivato, il che significa che non possono verificarsi interruzioni durante l'esecuzione di questo programma.
Ma lei come programmatore e un designer sono liberi di abilitare gli interruzioni che è quello che stiamo dicendo qui. E'possibile abilitare interruzioni all'interno della subroutine di interruzione e vi richiederei, consiglierei di esercitare grande cautela nel cercare di riabilitare le interruzioni all'interno della subroutine di interruzione.
Ovviamente, quello che dopo sarebbe arrivato è il programma vero che si eseguirebbe nella subroutine. Ora, se la fonte di un'interruzione a più fonti, è vostra responsabilità che sia responsabilità del programma di resettare la bandiera, in modo che la successiva impostazione della bandiera genererà un'altra interruzione e una volta effettuata è possibile ripristinare il contesto di sistema e restituire significato quando si ritorna, automaticamente il sistema recupererà il registro degli stack, il registro di stato e il contatore del programma dalla pila e lo inserirà nei rispettivi registri, cioè il registro di stato e il contatore del programma che significa che si tornerà alla programma principale che era stata interrotta e si farà riprendere la tua esecuzione da quel punto in poi. Così è il modo in cui le cose succedono in una subroutine di interruzione.
(Riferimento Slide Time: 25:40) Ora, come ho accennato come fa un interrupt gestire le variabili? Come comunica con il programma principale? Non è che succede un'interruzione, si entra in subroutine di interruzione, si fa qualcosa lì e si torna, no. Spesso i tempi, si vorrebbero convogliare al programma principale che è accaduto un'interruzione e questo è l'input fornito. E questo avviene utilizzando le variabili, ma queste variabili non sono variabili normali, devono essere dichiarate volatili e volatili è una parola chiave, quindi bisogna accodare questo nome 'volatile' davanti a qualsiasi variabile.
Quello che fa spesso è che il compilatore C manterrà una copia di variabili nei registri perché la lettura di qualsiasi cosa da un registro avviene velocemente ma se la variabile principale è nella memoria, potrebbe non ottenere il suo esatto valore. Ma utilizzando questa parola chiave, si sta dicendo al compilatore di non utilizzare una copia di quel valore, andare nella memoria riservata a quella variabile, recuperare il valore da lì e poi passarlo.
E come regola di pollice, tutte le variabili associate ai porti e alle interruzioni devono essere dichiarate volatili. E vedremo quell' esempio sia in questa o successive lezioni. (Fare Slide Time: 27:03) Quindi ecco una checklist di cose che dovete eseguire nel programma principale in modo che le interruzioni possano accadere, se accadono, e se accadono possono essere servite. È necessario aver abilitato le interruzioni sia nel modulo che nel bit di interruzione globale. È necessario avere la subroutine di interruzione per ciascuna delle interruzioni abilitate, è necessario riconoscere che il significato di interruzione è necessario disabilitare la bandiera all'interno della subroutine di interruzione.
E se si utilizzano delle variabili, bisogna assicurarsi che siano dichiarati volatili. Ora quello che faremo è illustrare come si può sperimentare con interruzioni sulla vostra casella di pranzo MSP430. Così nel primo esercizio collezioniamo la scatola del pranzo al nostro portatile e discuteremo di questo codice, scariceremo questo codice sulla mensola lunare e utilizzando la periferica sulla scatola del pranzo, vedremo come possono essere generate interruzioni e come possono essere servite, ecco come è possibile eseguire una subroutine di interruzione in risposta ad un'interruzione sulla scatola del pranzo.
Quindi prenota la tua scatola del pranzo e la connetti al tuo portatile e lasciaci passare dal codice, in modo da capire come funziona il codice e come puoi modificarlo. Così nel primo esercizio useremo lo switch sul lunchbox così come il LED sulla scatola del pranzo per illustrare questa interruzione generata dall'interruttore. (Fare Slide Time: 28:45) Così come si sa, sul lunchbox c'è un interruttore collegato al bit 3, cioè P 1,3 si sa che quello è l'interruttore collegato a questo. Sai anche che questo interruttore è collegato nella modalità pull up, significa che c'è un resistore e un interruttore come questo l'interruttore è delimitato dall'altra parte.
Questo lato della resistente pull up è collegato a VCC e questa giunzione qui è collegata a P 1,3 che è il senso di tiratura del registro.
E sai anche che abbiamo un LED collegato su P 1,7. Quindi utilizzeremo le risorse disponibili sulla casella di pranzo stessa per illustrare questa idea di interruzione e come un evento sull'interruzione o interruzione generata da questo switch può essere gestito con una subroutine di interruzione.
Quindi dobbiamo includere, come noto, questo file di intestazione nel nostro programma C. Abbiamo già definito che abbiamo un interruttore che è al bit 3. Ora, vedi un po' 3 è una maschera, che significa, quello che in realtà è, è per questo che ho 8 bit come questo è un po' 0, da 1 a 7, quindi questo è 0, 1, 2, 3, quindi significa 1 0 0 0 0 0 0 0 0 0 che è il significato del bit 3.
E useremo questo per mascherare questo bit particolare o per fare operazioni di bit su questo bit come e quando richiesto. Similmente il rosso è un bit definito come un bit mascherato 7, questo significa, quindi il bit 3 in realtà diventa 0 8 questo valore è 0 8 in X e il bit 7 essere 1 significa è 8 0 X, questo è il significato del bit 7. Ovvero il bit 7 è 1, i bit di riposo sono 0 - questo è il significato di queste maschere. Ora nel nostro programma principale, come sempre facciamo, siamo disabilitati il timer watchdog. E dobbiamo ora dire al microcontrollore che vogliamo usare il rosso, vogliamo usare LED su pin 1,7, quindi quel pin deve essere dichiarato come output. E vogliamo usare è un interruttore su pin P 1,3 e che deve essere dichiarato come input. E quindi questa istruzione, si sta decidendo la direzione della P 1,7 bit come output.
Il pin P 1,3 viene dichiarato come input. Si ha anche l'abilitazione e la resistenza di pull-up interna utilizzando questo registro REN. E poi si sta scrivendo un bit corrispondente da 1 in P1 in modo che si stia abilitando anche la tiratura interna resistente. Ma attenzione, che ci sia anche una tiratura esterna resiste così, questa istruzione è superflua ma non fa male.
E poi, stai dicendo che vuoi devi decidere dove ti trovi, come vuoi generare l'interruzione - vuoi generare l'interruzione sul bordo in calo per l'alzata. Dato che sono nel registro di abilitazione all'interruzione, sono, registro di selezione edge, sto scrivendo 0 che significa che ho, ho scelto di generare un'interruzione sul bordo dell'alzata. E poi, sul registro di abilitazione dell'interruzione faccio che quel bit corrispondente che sia un bit 3 pari a 1, questo significa che ho permesso che l'interruzione avvenga su questo pin. E poi questa istruzione viene utilizzata per trasformare l'interruzione globale del bit a 1, ora sono pronto.
(Riferimento Slide Time: 32 :56) Se torno a quel diagramma di blocco, praticamente quello che ho fatto è, qui usando quell' istruzione ho acceso questo e l'istruzione precedente ho abilitato il bit particolare. Ora siamo pronti a fare qualcosa nel programma principale.
(Riferirsi Slide Time: 33:15) Ma nel programma principale in questo caso particolare non c'è niente da fare e quindi semplicemente, come vedete qui, ci asporremo qui in un loop infinito mentre uno. Quindi è, il tuo programma principale non sta facendo nulla, in attesa che qualcosa accada e in questo caso che qualcosa sia un'interruzione esterna che verrà generata perché si preme il commutatore su pin 1,3 porta 1,3.
Quando questo accade, prima di quello, vedi di aver dichiarato di essere fatto #pragma e poi vettore che hai detto si riferisce a questo vettore, porta 1 vettoriale e hai nominato per la subroutine port_1. E questa è la subroutine di interruzione. Quindi e questa è l'intera subroutine di interruzione per l'interruzione generata sulla porta 1.
Cosa succede nel momento in cui si preme lo switch e quando si preme un interruttore, perché c'è un interruttore, l'interruttore è già tirato su, quando si preme un interruttore si ottiene una transizione elevata. E come vedete qui, avete selezionato un'interruzione per il bordo in salita. Quindi quello che succederà è quando si preme il passaggio che andrà in basso, questo non genera un'interruzione. Ma dopo un po' quando si rilascia l'interruttore, questo atto di rilascio dell'interruttore genererà un'interruzione. (Fare Slide Time: 34:36) Ora, si prega di notare qui che stiamo richiamando questo programma un brutto ISR, significa questo non è un ottimo stile di scrittura di una subroutine di interruzione, perché? Come ho accennato la subroutine di interruzione deve essere tenuta breve, e come vedete qui, c'è scritto un programma di ritardo. Come vedete qui abbiamo scritto un piccolo programma di ritardo. Questo non è un buon modo di scrivere un'interruzione ma spiegherò perché questo è necessario.
(Riferimento Slide Time: 35 :07) Ora quando l'interruttore viene premuto si andrà a basso ma come sappiamo, quando un interruttore viene premuto spesso può rimbalzo. Quindi l'atto di premere un interruttore può generare questo. Così si vede che il bordo più alto può accadere e poi si terrà basso per tutto il tempo in cui si mantiene premuto lo switch e quando si rilasciano di nuovo più eventi è probabile che accada, può accadere più spigoli in salita.
E la durata di questi rimbalzi è tale che il microcontrollore tratterà ciascuno di questi rimbalzi come una singola interruzione, anche se si preme il quale solo una volta, potrebbe interpreti che avete premuto più volte l'interruttore. E quindi eliminare quell' ambiguità, a questo punto avete atteso che questi rimbalzi a morire di.
Ma che dire del rimbalzo che può accadere quando si preme lo switch? Purtroppo nel nostro programma non ci siamo affrontati e quindi è possibile, comunque vediamo cosa fa il programma, quando questo verifica se davvero l'interruzione è avvenuta perché si è premuto l'interruttore.
(Riferimento Slide Time: 36:19) Così P1 IFG, è 1? Isolare quel bit utilizzando questa & operazione. Questo è superfluo perché da quando hai disabilitato il resto delle interruzioni, questa interruzione sarebbe successa solo perché hai premuto il interruttore ma è una buona idea. Quando questo accadrà, e quando accadrà? Quando si preme lo switch e lo rilasciano o se mentre premendo c'è un rimbalzo dello switch e che genera anche un segnale di bordo in salita si toggono immediatamente il LED sulla porta 1 bit 7, poi si rimanda indietro per i rimbalzi per morire e poi si ripristina quel flag in modo che, la prossima volta in cui l'utente preme un interruttore può generare t0, può generare un'interruzione e può eseguire questo programma.
E perché chiamiamo questo esempio di subroutine di interruzione come non un buon esempio? È perché abbiamo usato una subroutine di ritardo; non consigliamo di utilizzare la subroutine di ritardo nel programma di interruzione.
Ora, come ci occupiamo di questo? Beh, assicurati di non dover de - bounce il tuo interruttore.
Ora, se questo viene letto usando il polling, questo è un buon metodo. Ma leggere un interruttore o de - rimbalzare l'interruttore usando il ritardo in un'interruzione è un completo no - no. Quindi quello che facciamo è, guardiamo un altro esempio.
(Riferimento Slide Time: 37:51) In questo esempio, utilizzeremo un interruttore esterno e questo è il cablaggio che si dovrebbe collegare un interruttore esterno e de - rimbalzo utilizzando l'hardware. Come abbiamo discusso in passato, un modo per de - bounce in hardware è mettendo un condensatore attraverso l'interruttore. Questo condensatore agisce come un filtro passa basso e uccide qualsiasi rimbalzo degli interruttori. (Fare Slide Time: 38:17) Così il modo in cui questo sembrerebbe è, qui si ha un pull-up resistore, qui si ha un interruttore e in tutto ciò che abbiamo messo un condensatore, e poi questo segnale va a un pin che citerò brevemente quello che è. In questo caso è P 1,4. Quindi è necessario collegare un interruttore in questa configurazione e collegarlo a Porta 1 bit 4, qui 1 bit 4. (Fare Slide Time: 38:41) Si è dedicati, si sta dedicando per un nuovo switch che si collega sul breadboard.
Continueremo ad utilizzare il LED di bordo su 1,7. Ora si vede, abbiamo tutti gli stessi, vogliamo un interruttore all'avanguardia, il che significa che se premi lo switch mi