PIC18F4550 ed interrupt su PORTB

  • iv3ynb
  • Autore della discussione
  • Anziano Utente
  • Anziano Utente
Di più
4 Anni 3 Mesi fa - 4 Anni 3 Mesi fa #1 da iv3ynb
PIC18F4550 ed interrupt su PORTB è stato creato da iv3ynb
Ciao a tutti,

lavoro con MPLABX 3.10 XC8 1.34 standard e PicKit3

ho un interrupt su PORTB che si comporta così: voglio far lampeggiare un led di test alla pressione di RB0 e RB1 intercettati da interrupt. Ho inizialmente settato RB6 e RB7 come input, dopo la programmazione l'ìnterrupt ha funzionato, solo che all'atto di STACCARE il PicKit3 dalla scheda, il tutto si bloccava.
Pensandoci bene: RB7 e RB6 meglio lasciarle stare, visto che servono per la programmazione del micro.
Ho quindi modificato usando RB0 ed RB1 per far scattare l'interrupt, spostando parte dei collegamenti del display LCD su un'altra porta; ma l'interrupt non scatta proprio... il compilatore non mi da warning di alcun genere, davvero dopo giorni di prove, non so che pesce pigliare.
Vi lascio il mio codice, se qualcuno volesse darci un'occhiata...

Ringrazio e saluto
Matteo IV3YNB
Code:
//************************************* // INCLUDES //************************************* #include <xc.h> #include "PIC18F4550_config.h" #define LCD_DEFAULT //non spostare da qui!!! va prima di inc LCD #include "LCD_44780.h" //by www.LaurTec.it mod IV3YNB 2015 #include "LCD_44780.c" //by www.LaurTec.it mod IV3YNB 2015 #include "delay.h" //by www.LaurTec.it #include "delay.c" //by www.LaurTec.it #include "custom_chars.c" //by IV3YNB prova a vedere se qui funziona #include "intEEPROM.h" //by www.LaurTec.it #include "intEEPROM.c" //by www.LaurTec.it #include "vars.c" //by IV3YNB #include "kpad.c" //by IV3YNB //#include "encoder.c" //by IV3YNB #include "managefreq.c" //by IV3YNB #include "memofreq.c" //by IV3YNB #define _EEPROMSIZE 256 #define ENC_PLS LATBbits.RB0 //PULSAZIONE ENCODER #define ENC_BUT LATBbits.RB1 //PULSANTE ENCODER #define ENC_DIR LATAbits.RA0 //DIREZIONE ENCODER #pragma config PBADEN = OFF // Ingressi digitali //OKKIO OKKIO OKKIO //setta dati iniziali in EEPROM - prima riga (questi dati non devono essere scritti ogni volta!!!) __EEPROM_DATA(0x00, 0xD5, 0x9F, 0x80, 00, 00, 00, 00); //14MHz //__EEPROM_DATA(04, 05, 06, 07, 00, 00, 00, 00); //************************************* // INTERRUPT su PORTB //************************************* __interrupt (high_priority) void ISR_alta (void) { //void high_priority interrupt ISR_alta (void){ //controllo se interrupt è generato da PORTB if (INTCONbits.RBIF == 1){ //pausa filtraggio spike //for (i=0; i<10000; i++){ //} // Controllo la pressione di RB0 if (PORTBbits.RB0 == 1) { LATCbits.LATC0 = 1; delay_ms(500); LATCbits.LATC0 = 0; delay_ms(500); LATCbits.LATC0 = 1; delay_ms(500); LATCbits.LATC0 = 0; delay_ms(500); //reset del FLAG INTCONbits.RBIF = 0; } // Controllo la pressione di RB0 if (PORTBbits.RB1 == 1) { LATCbits.LATC1 = 1; delay_ms(500); LATCbits.LATC1 = 0; delay_ms(500); //reset del FLAG INTCONbits.RBIF = 0; } } } //************************************* // PROTOTIPI DI FUNZIONE //************************************* int board_initialization (void) { //settaggio porte di comunicazione /* * LATA0 = ENC DIRECTION input 0b0000001 * LATA1 = FILTRI output * LATA2 = FILTRI output * LATA3 = FILTRI output * LATA4 = FILTRI output * * LATB0 = ENC PULSE input inter 0b00000011 * LATB1 = ENC BUTTON input inter * LATB2 = LCD D0 output * LATB3 = LCD D1 output * LATB4 = LCD D2 output * LATB5 = LCD D3 output * LATB6 = riservato ICSP output * LATB7 = riservato ICSP output * * LATC0 = LED x TEST output 0b00000000 * LATC1 = LCD RW output * LATC2 = LCD LED output * LATC3 = N/A output * LATC4 = FREE output NON ASSEGNABILE a COSTANTE * LATC5 = FREE output NON ASSEGNABILE a COSTANTE * LATC6 = LCD E output * LATC7 = LCD RS output * * LATD0 = 4x4 keyb cols output 0b11110000 * LATD1 = 4x4 keyb cols output * LATD2 = 4x4 keyb cols output * LATD3 = 4x4 keyb cols output * LATD4 = 4x4 keyb rows input * LATD5 = 4x4 keyb rows input * LATD6 = 4x4 keyb rows input * LATD7 = 4x4 keyb rows input * * LATE0 = DDS data output 0b00000000 * LATE1 = DDS clock output * LATE2 = DDS acknowledge output * * PIN liberi: * LATA5 (input/output) * LATC4 (solo input) * LATC5 (solo input) */ LATA = 0x00; //poni inizialmente tutte le porte a livello 0 TRISA = 0b00000001; LATB = 0x00; TRISB = 0b00000011; LATC = 0x00; TRISC = 0b00000000; LATD = 0x00; TRISD = 0b11110000; LATE = 0x00; TRISE = 0b00000000; INTCON2bits.RBPU = 0; //PULL-UP R attive su PORTB //settaggio interrupts INTCONbits.RBIE = 1; //abilita interrupts su PORTB //RCONbits.IPEN = 0; //abilita modalità compatibile PIC16 (default = 0) INTCONbits.RBIF = 0; //reset FLAG prima di attivare l'interrupt INTCONbits.GIE = 1; //abilito interrupt GLOBALE INTCONbits.PEIE = 1; //abilito interrupt PERIFERICHE //scrivi in CGRAM i carateri custom custom_chars (); delay_ms(100); //kpad in modalità "seleziona banda" di DEFAULT band = 1; //filtro OFF di DEFAULT cw = 0; //aa0 = encoder_a; //lettura encoder a vuoto //bb0 = encoder_b; //enc_cnt = 0; //rotazione = FALSE; //fstep = 1000; //prima frequenza da visualizzare fArray32[3] = internal_EEPROM_read(0000); fArray32[2] = internal_EEPROM_read(0001); fArray32[1] = internal_EEPROM_read(0002); fArray32[0] = internal_EEPROM_read(0003); freq = (fArray32[0] + (fArray32[1]<<8) + (fArray32[2]<<16) + (fArray32[3]<<24)); } //************************************* // PROGRAMMA PRINCIPALE //************************************* int main (void) { //inibisce warning generato per variabili non in uso //#asm /* GLOBAL _yy GLOBAL _freq0 GLOBAL _cnt GLOBAL _enc_cnt GLOBAL _fArray GLOBAL _rotazione */ //#endasm delay_ms(100); board_initialization(); //richiama settaggi iniziali scritti in MACRO delay_ms(100); keyok = 0; //tastierino NON premuto (tipo un flag) LCD_initialize (20); //20 = 20MHz di clock delay_ms(100); LCD_write_char ('P'); //scrive messaggio di benvenuto LCD_write_char (' '); delay_ms(500); LCD_write_char ('A'); LCD_write_char (' '); delay_ms(500); LCD_write_char (rusd); LCD_write_char (' '); delay_ms(500); LCD_write_char (rusi); LCD_write_char (' '); delay_ms(500); LCD_write_char ('C'); LCD_write_char (' '); delay_ms(500); LCD_write_char ('T'); LCD_write_char (' '); delay_ms(500); LCD_write_message (" 1.0"); delay_ms(1000); LCD_goto_line (2); LCD_write_message ("IV3YNB uC - 2021"); delay_ms(2000); /*delay_ms(250); LCD_goto_line (2); delay_ms(250); LCD_write_message ("PIC18F4550 v1.00"); delay_ms(250);*/ LCD_clear(); LCD_cursor(0,0); //cursore (attivo/non att, blink/no blink) delay_ms(10); LCD_goto_xy (1,1); LCD_write_message ("A:"); LCD_goto_xy (12,1); LCD_write_message ("KHz"); //************************************* // CICLO INFINITO //************************************* while (1) { //polling keypad 4x4 kpad (); LATAbits.LATA5 = 1; delay_ms(500); LATAbits.LATA5 = 0; delay_ms(500); LATAbits.LATA5 = 1; delay_ms(500); LATAbits.LATA5 = 0; delay_ms(500); //polling encoder //encoder (); //delay_ms(10); //se keypad o encoder cambiano, allora chiamare managefreq()) //managefreq(); //gestione frequenza //if (rotazione == TRUE) { //managefreq(); //memorizza ultima freq //memofreq(); //rotazione = FALSE; } }

non esistono domande stupide, ma le risposte...
Ultima Modifica 4 Anni 3 Mesi fa da iv3ynb.

Si prega Accesso o Crea un account a partecipare alla conversazione.

  • firstcolle
  • Platino Utente
  • Platino Utente
Di più
4 Anni 3 Mesi fa #2 da firstcolle
Risposta da firstcolle al topic PIC18F4550 ed interrupt su PORTB
Ciao,
visto che usi gli interrupt in altra priorità forse dovresti mettere IPEN = 1.
detto questo io non mi sono mai fidato degli interrupt su cambio di stato di PORT B... se ti serve identificare solo un passaggio da 0 a 1 o da 1 a 0 ti conviene valutare l'uso di INT0 - INT1 su RB0 e RB1

Si prega Accesso o Crea un account a partecipare alla conversazione.

  • iv3ynb
  • Autore della discussione
  • Anziano Utente
  • Anziano Utente
Di più
4 Anni 3 Mesi fa #3 da iv3ynb
Risposta da iv3ynb al topic PIC18F4550 ed interrupt su PORTB
Grazie, non sono un gran conoscitore degli interrupt, fino ad ora usavo il polling ma era ora di sforzarsi per fare un passo in avanti per lo meno a livello "culturale" :unsure:

Proverò ciò che suggerisci.

Ad maiora
Matteo IV3YNB

non esistono domande stupide, ma le risposte...

Si prega Accesso o Crea un account a partecipare alla conversazione.

  • iv3ynb
  • Autore della discussione
  • Anziano Utente
  • Anziano Utente
Di più
4 Anni 3 Mesi fa #4 da iv3ynb
Risposta da iv3ynb al topic PIC18F4550 ed interrupt su PORTB

firstcolle ha scritto: Ciao,
visto che usi gli interrupt in altra priorità forse dovresti mettere IPEN = 1.


Eh... era ovvio... ma dopo che mi sono perso nel codice, ho perso la retta via :unsure:

firstcolle ha scritto: detto questo io non mi sono mai fidato degli interrupt su cambio di stato di PORT B...


nemmeno a me piaceva, a pelle, questa soluzione, vista la presenza di RB6 e RB7 che mi han dato comunque noia... i tuoi motivi invece? :dry:

firstcolle ha scritto: se ti serve identificare solo un passaggio da 0 a 1 o da 1 a 0 ti conviene valutare l'uso di INT0 - INT1 su RB0 e RB1


Fatto... tutto OK ora, grazie mille !!! B)

a presto,
Matteo IV3YNB

non esistono domande stupide, ma le risposte...

Si prega Accesso o Crea un account a partecipare alla conversazione.

  • firstcolle
  • Platino Utente
  • Platino Utente
Di più
4 Anni 3 Mesi fa #5 da firstcolle
Risposta da firstcolle al topic PIC18F4550 ed interrupt su PORTB
Funziona ora?

il mio problema sui cambi di stato è che, non ricordo bene, hanno un bug e vanno gestiti con una particolare sequenza di lettura/scrittura dei registri. ma li ho trovati poco affidabili. sicuramente meglio gli INT0-1.

Si prega Accesso o Crea un account a partecipare alla conversazione.

Moderatori: Mauro LaurentiPinnaStefAMatteo Garia

Registrati al sito

Accedi a tutte le risorse e articoli non visibili pubblicamente, puoi registrarti con pochi passi.

Registrati al sito LaurTec.

Forum - Ultimi messaggi