Utilizzo di più interrupt esterni in PIC


9

Ho usato PIC16F877( scheda tecnica ) per diversi progetti. Per una singola interruzione della sostituzione dei pin esterni, è possibile utilizzare l' PORTB0interruzione. Ma ora ho bisogno di supportare 8 interrupt di cambio pin esterni indipendenti, in un singolo circuito.

Nel foglio dati dice che ci sono 15 interrupt in PIC16F877, ma immagino che siano contati inclusi gli interrupt di overflow del timer ecc ... che sono inutili in questo caso.

Questo è ciò che dice la scheda tecnica sul INTCONregistro.

inserisci qui la descrizione dell'immagine

Posso avere 4 interrupt indipendenti utilizzando bit0, RBIF? Rappresenta il cambiamento in PB7:PB4. Come posso identificare quale pin è cambiato, leggendo il valore della porta nella routine di interrupt?

Anche io ricevo risposte positive a quanto sopra, ho bisogno di 8 interruzioni? ovviamente posso ancora usare INTE, per PORTB0cambiare. Quindi 4 + 1 = 5, ma per quanto riguarda gli altri 3? (Comunque essendo tutti e 8 gli eventi di interruzione sono dello stesso tipo, la 4 + 1 + 3 = 8cosa sembra brutta, vero?)

Non ci sono altri compiti pesanti previsti dal microcontrollore se non il monitoraggio di 8 pin. (Parlando delle altre attività, dovrà mantenere una serie di variabili contatore separate e spesso trasmettere seriamente al PC circa 4 byte)

Eventuali suggerimenti sono ben accetti Anche se si tratta di cambiare il microcontrollore con uno più adatto (ma ... non dirmi di andarmene da PICs).


2
Senza utilizzare gli interrupt, è possibile monitorare i pin nel programma principale. Ma non è perfetto. In alternativa, puoi scegliere Arduino. Sebbene non sia PIC, è piuttosto semplice, capirai facilmente poiché hai già familiarità con i PIC.
Anubi

1
Se usi l'interruzione RBIE puoi semplicemente bufferare il valore precedente ogni volta e un XOR per trovare cosa è cambiato. Dovrebbe essere abbastanza veloce da eseguire.
PeterJ,

@PeterJ non l'ho capito bene. Buffer quale valore?
Nome in codice SC

@PeterJ fantastico! aspettando ...
Nome in codice SC

1
Un modo è quello di utilizzare un gate esterno a 8 ingressi (come il 74LS30 ai vecchi tempi) per combinare i segnali esterni su un pin di interruzione. Dato che il 74 (HC) 30 è un gate NAND, avresti bisogno di tutti gli ingressi in alto nello stato di riposo - dovrebbero anche essere collegati ai pin delle porte in modo da poter identificare quali interruzioni erano attive leggendo la porta.
Brian Drummond,

Risposte:


3

Questo è lo pseudo-codice C per spiegare un'idea. Utilizza ed OR esclusivo per capire quali pin sono cambiati e chiamerà i tuoi diversi gestori all'interno di un interrupt RBIE. A seconda di quanto sia critica l'applicazione, potresti voler controllare in che modo il PIC gestisce situazioni come il cambio di una porta durante l'esecuzione dell'interrupt per assicurarti di non perdere alcun evento.

int old_port_b;

void isr_handler()
{
    int new_port_b, changed_pins;
    new_port_b = read_port_b();
    changed_pins = new_port_b ^ old_port_b;
    if (changed_pins | 1)
        rb0_hander();
    if (changed_pins | 2)
        rb1_hander();
        // ... etc
    old_port_b = new_port_b;
}

int main()
{
    old_port_b = read_port_b();
    enable_interrupt();
}

Ho capito, grazie! ma non è la risposta esatta che sto cercando. In questo modo, puoi monitorare RB7:RB4solo 4 pin. Ma sto chiedendo un modo per monitorare 8 pin. qualche suggerimento?
Nome in codice SC

Immagino che ci sia un motivo per cui non puoi usare RB0 - RB7 per cui sopra dovrebbe funzionare? Altrimenti non riesco davvero a pensare a un modo, se trigerrare rapidamente il codice non è vitale potresti usare lo stile di codice sopra in un interruzione del timer (o solo nel ciclo principale).
PeterJ,

Per quel PIC, se hai bisogno di usare gli interrupt per farlo, il trucco XOR su RB4: RB7 e quattro interruzioni per RB0: RB3 è la strada da percorrere. Se non hai bisogno dell'interrupt, esegui il polling dell'intera porta nel tuo codice o usa un interrupt del timer per gestire il polling se hai bisogno di una frequenza di campionamento elevata
Scott Seidman,

and four interrupts for the RB0:RB3? PIC16F877 non supporta alcun interrupt per RB1:RB3, eh?
Nome in codice SC

Mi era sfuggito che nel foglio dati, stavo assumendo che coprisse l'intera porta. Ma ho visto l'altro tuo commento circa una volta al secondo, quindi penso che faresti meglio a eseguirlo nel tuo ciclo principale. Con gli interrupt dovrai occuparti dell'aggiornamento delle variabili in qualsiasi momento durante l'esecuzione e di come gestire le modifiche dei pin mentre l'interrupt è in esecuzione. Sembra davvero che lo complicherà solo per nessun guadagno reale. L'unica eccezione che mi viene in mente è se si desidera utilizzare wake from sleep in interrupt, nel qual caso è necessario hardware MUX.
PeterJ,

1

Quella parte ha solo 4 interruzioni di cambio pin e alcune altre che puoi impostare sui bordi selezionati. Una strategia sarebbe quella di rilevare esternamente una variazione del valore di 8 bit, quindi interrompere la mancata corrispondenza. Questo diventa disordinato nell'hardware, ma sarà esattamente quello che vuoi.

I parametri importanti che non hai indicato sono la velocità necessaria per rispondere a una modifica del pin e per quanto tempo durerà una modifica del pin affinché sia ​​valida. A seconda delle risposte, è possibile eseguire il polling in base a un interrupt regolare nel firmware. Il 16F877 può funzionare a una frequenza di istruzione di 5 MHz e il controllo di una modifica richiederebbe solo poche istruzioni. Supponiamo che tu abbia impostato l'interrupt ogni 50 istruzioni. Ciò lascerebbe buona parte del tempo del processore al codice di primo piano. La frequenza di interruzione sarebbe di 100 kHz e il periodo di 10 µs. Ovviamente il codice di primo piano deve ancora vedere il flag di modifica e fare qualcosa al riguardo, quindi il tempo di risposta sarà superiore a 10 µs, ma non hai detto nulla su ciò che devi fare quando viene rilevata una modifica. Se questo deve solo rispondere nel tempo umano,


Mi dispiace per i dettagli mancanti. Poiché il tasso di risposta previsto once per secondsarà sufficiente. Quando viene rilevato un cambio di perno (solo un fronte, diciamo in aumento), un contatore (variabile) deve essere incrementato. Nel loop principale, deve monitorare i valori del contatore e quando si supera un certo valore, quattro byte devono essere trasmessi USARTal PC. Quindi reimpostare il valore del contatore rilevante su zero. Semplice come quella. Immagino che l'opzione di polling andrà bene, vero?
Nome in codice SC

2
Una volta al secondo ! Quindi a cosa servono tutte le interruzioni dolorose? Questo è facilmente eseguibile periodicamente con il polling. Qual è il problema allora?
Olin Lathrop,

um ... ho pensato che sarebbe meglio dato che ce ne sono 8 e inoltre, la risposta non può essere prevista (ma quel valore può essere assunto come minimo). Hey! le persone possono fare errori, giusto .. :(
Nome in codice SC

1

È possibile utilizzare la porta NAND a 8 ingressi, come indicato da @Brian Drummond, per generare un interrupt sul pin INT e anche collegare le proprie fonti di interruzione al registro a scorrimento a 8 bit in parallelo / seriale come "74HC165N", quindi sarà necessario leggere semplicemente i dati da quel registro a scorrimento dopo l'interruzione è aumentato e ciò ti darà le informazioni sulla tua vera fonte di interruzione ... potrebbe non essere il modo più veloce, ma facile da espandere e utilizzerà non più di 5 pin, e se aggiungi il sistema di controllo dell'indirizzo (MUX, LATCH, ...), avrai bisogno di un solo pino per la notifica di interruzione e altri pin potrebbero essere riutilizzati in momenti diversi per risorse diverse;)

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.