- Messaggi: 40
- Ringraziamenti ricevuti 0
Scelta del PIC per piccola serie dopo il prototipo
8 Anni 7 Mesi fa #11
da MauroFx
Risposta da MauroFx al topic Scelta del PIC per piccola serie dopo il prototipo
16f1847. Noto con piacere che qualcuno di voi lo conosce bene. Vedo che la gestione degli interrupt è molto diversa dai pic18. Mi sembra però che sia più semplice nel pic16, ma ho difficoltà a trovare i comandi corretti nelle specifiche in inglese. Mi interesserebbero in particolare gli interrupt during sleep della porta B. Ho cercato senza troppo successo un tutorial adeguato. Puoi darmi qualche ragguaglio ?
Si prega Accedi o Crea un account a partecipare alla conversazione.
- MauroFx
- Autore della discussione
- Senior Member
Riduci
Di più
8 Anni 7 Mesi fa #12
da MauroFx
Risposta da MauroFx al topic Scelta del PIC per piccola serie dopo il prototipo
L'istruzione SLEEP() è davvero semplice, senza GIE e tutti gli altri settaggi. L'unica cosa limitante è che non devo introdurre ritardi o timer nel codice dopo SLEEP(), pena il perdermi cambi di valore su interrupt, successivi al primo. Per il momento ho risolto ripetendo il codice nei casi dove occorra, per verificare se ci sono altri cambi.
Devo però ancora capire bene come funziona l'interrupt "normale". Qualcuno può aiutarmi ? Mi basterebbe almeno un frammento di codice con la sequenza completa del richiamo di tutte le funzioni necessarie (16f1847 !).
Devo però ancora capire bene come funziona l'interrupt "normale". Qualcuno può aiutarmi ? Mi basterebbe almeno un frammento di codice con la sequenza completa del richiamo di tutte le funzioni necessarie (16f1847 !).
Si prega Accedi o Crea un account a partecipare alla conversazione.
- MauroFx
- Autore della discussione
- Senior Member
Riduci
Di più
- Messaggi: 40
- Ringraziamenti ricevuti 0
8 Anni 7 Mesi fa #13
da Mauro Laurenti
Risposta da Mauro Laurenti al topic Scelta del PIC per piccola serie dopo il prototipo
Se fai riferimento al testo XC8 Step by Step, capitolo delle interruzioni, rimane tutto valido ma i PIC16 hanno solo il livello ad alta priorita' mentre i PIC18 hanno livello alto e basso.
Il testo riporta un esempio di un PIC18 in modalita' compatibile con PIC16.
Saluti,
Mauro
Il testo riporta un esempio di un PIC18 in modalita' compatibile con PIC16.
Saluti,
Mauro
Si prega Accedi o Crea un account a partecipare alla conversazione.
8 Anni 7 Mesi fa #14
da MauroFx
Risposta da MauroFx al topic Scelta del PIC per piccola serie dopo il prototipo
Come temevo c'è qualcosa che mi sfugge. Nella spiegazione della modalità compatibile PIC18-PIC16, è ovvio che la modalità compatibile deve essere dichiarata solo per il PIC18, quindi si comincia col GIE, PEIE, INTE, IOCE e si controlla la provenienza con IOCF. Ho provato ad allocare la chiamata della funzione per la gestione delle interruzioni con #pragma code, ma non è una istruzione riconosciuta col 18f1847, come pure ho provato anche a posizionare la chiamata della funzione con _asm e _endasm, ma anche queste non vengono riconosciute. Il frammento di codice è il seguente:
§=====================================================================
void Gestisci_Interruzione (void);
#pragma code vettore = 0004h //warning: (335) unknown pragma "code"
void Salto_Vettore (void) {
_asm vettore _endasm //error: (195) expression syntax
}
#pragma code //warning: (335) unknown pragma "code"
#pragma interrupt Gestisci_Interruzione //warning: (335) unknown pragma "interrupt"
void Gestisci_Interruzione (void) {
//codice per la gestione delle interruzioni
}
=====================================================================
Il vettore di interruzione è 0004h, come indicato nel datasheet del 16f1847
E qui non riesco ad andare avanti. HELP !
§=====================================================================
void Gestisci_Interruzione (void);
#pragma code vettore = 0004h //warning: (335) unknown pragma "code"
void Salto_Vettore (void) {
_asm vettore _endasm //error: (195) expression syntax
}
#pragma code //warning: (335) unknown pragma "code"
#pragma interrupt Gestisci_Interruzione //warning: (335) unknown pragma "interrupt"
void Gestisci_Interruzione (void) {
//codice per la gestione delle interruzioni
}
=====================================================================
Il vettore di interruzione è 0004h, come indicato nel datasheet del 16f1847
E qui non riesco ad andare avanti. HELP !
Si prega Accedi o Crea un account a partecipare alla conversazione.
- MauroFx
- Autore della discussione
- Senior Member
Riduci
Di più
- Messaggi: 40
- Ringraziamenti ricevuti 0
8 Anni 7 Mesi fa #15
da permax1958
Risposta da permax1958 al topic Scelta del PIC per piccola serie dopo il prototipo
per usare l'interrupt on change sulla porta B si inizia abilitando gli interrupt globalmente GIE=1 PEIE=1 poi si abilita il modulo con l'interrupt on change enable bit IOCE=1 vedi registro INTCON, poi si sceglie individualmente per ogni pin della porta B che interessa se far avvenire l'interrupt sul fronte di discesa o su quello di salita con IOCBPx=1 per il fronte di salita e IOCBNx=1 per il fronte di discesa dove x indica il numero del pin, vedi i registri IOCBP e IOCBN.
Quando è rilevato il cambiamento di stato su un pin abilitato all'interrupt viene settato il relativo flag IOCBFx dove x indica il numero del pin, vedi registro IOCBF, e generato un interrupt, la routine di servizio dell'interrupt verifica da cosa è stato generato l'interrupt, nel nostro caso verifica quale flag IOCBFx è settato, lo gestisce e come ultima istruzione azzera il flag.
la funzione che gestisce l'interrupt deve essere definita in questo modo:
void interrupt mio_interrupt(void) {
}
facciamo un esempio di gestione di interrupt dove posso avere un interrupt ricevendo un carattere dalla USART e un interrupt sul fronte di discesa sul pin 0 della porta B
void interrupt mio_interrupt(void) {
// vedo se l'interrupt è causato da USART?
// verifico il flag di ricezione
if (PIR1bits.RCIF == 1 ) {
//Servo l'interrupt
// il flag RCIF viene azzerato automaticamente
}
// vedo se l'inerrupt è generato dal fronte di discesa sul pin 0 della porta B
if ((IOCBF0== 1) {
// servo l'interrupt
// alla fine azzero il flag
IOCBF0 = 0;
}
}
Quando è rilevato il cambiamento di stato su un pin abilitato all'interrupt viene settato il relativo flag IOCBFx dove x indica il numero del pin, vedi registro IOCBF, e generato un interrupt, la routine di servizio dell'interrupt verifica da cosa è stato generato l'interrupt, nel nostro caso verifica quale flag IOCBFx è settato, lo gestisce e come ultima istruzione azzera il flag.
la funzione che gestisce l'interrupt deve essere definita in questo modo:
void interrupt mio_interrupt(void) {
}
facciamo un esempio di gestione di interrupt dove posso avere un interrupt ricevendo un carattere dalla USART e un interrupt sul fronte di discesa sul pin 0 della porta B
void interrupt mio_interrupt(void) {
// vedo se l'interrupt è causato da USART?
// verifico il flag di ricezione
if (PIR1bits.RCIF == 1 ) {
//Servo l'interrupt
// il flag RCIF viene azzerato automaticamente
}
// vedo se l'inerrupt è generato dal fronte di discesa sul pin 0 della porta B
if ((IOCBF0== 1) {
// servo l'interrupt
// alla fine azzero il flag
IOCBF0 = 0;
}
}
Ringraziano per il messaggio: MauroFx
Si prega Accedi o Crea un account a partecipare alla conversazione.
- permax1958
- Premium Member
Riduci
Di più
- Messaggi: 91
- Ringraziamenti ricevuti 16
Moderatori: Mauro Laurenti, Pinna, StefA, Matteo Garia
Registrati al sito
Accedi a tutte le risorse e articoli non visibili pubblicamente, puoi registrarti con pochi passi.