Problema con Interrupt

  • x206
  • Autore della discussione
  • Giovane Utente
  • Giovane Utente
Di più
5 Anni 1 Mese fa - 5 Anni 1 Mese fa #1 da x206
Problema con Interrupt è stato creato da x206
Salve,

come da titolo ho un problema con un bottone che non esegue l'istruzione che si trova all'interno dell'interrupt ad alta

priorità, l'interrupt a bassa priorità è gestito da un timer ed è funzionante, vorrei capire dov'è l'errore, inoltre sempre

nell'interrupt a bassa priorità ho un secondo problema, far visualizzare il valore zero sull'LCD, così come ho scritto il codice

che vi posto, lo zero viene visualizzato ma è tremolante, giustamente...

Il programma serve a visualizzare su un display i valori letti da un encoder:
Code:
#include <xc.h> #include "LTlib.h" #include "module_UART.h" #include "module_UART.c" #include "LTlib_utilities.h" #include "LTlib_utilities.c" #include "module_IO.h" #include "module_IO.c" #include "module_I2C.h" #include "module_I2C.c" #include "LTlib_delay.h" #include "LTlib_delay.c" #include "PCF8574.h" #include "PCF8574.c" #define PCF8574 #include "LCD_44780_I2C.h" #include "LCD_44780_I2C.c" #define Encoder_SW PORTBbits.RB3 //Reset #define EncoderDT PORTBbits.RB5 //Encoder_DT #define EncoderCLK PORTBbits.RB4 //Encoder_CLK #define SPIKES_DELAY 1000 int NewPos=0; int OldPos=0; signed int count=0; //char zero[]={'0','\0'}; unsigned int i; //************************************************* // Gestione Interrupt //************************************************* __interrupt (high_priority) void ISR_alta (void) { if (INTCONbits.RBIF == 1 ) { INTCONbits.RBIF = 0; if(Encoder_SW == 0){ Reset(); } } } __interrupt (low_priority) void ISR_bassa (void) { // Controllo che l'interrupt sia stato generato dal Timer0 if (INTCONbits.TMR0IF == 1){ // Resetto il flag d'interrupt INTCONbits.TMR0IF = 0; NewPos = EncoderDT; if(NewPos != OldPos){ if(EncoderCLK != NewPos){ count++; } else{ count--; } } if(count == 0){ LCD_goto_xy(14,1); LCD_write_integer(count,0,LCD_ZERO_CLEANING_OFF); } LCD_goto_xy(11,1); LCD_write_integer(count,4,LCD_ZERO_CLEANING_ON); } UART1_write_byte(count); OldPos = NewPos; } void main(void) { // Setto le porte in input IO_set_all_ports_as_inputs(); //Inizializzo il display LCD_initialize (20); //Accendo retroilluminazione LCD LCD_backlight (LCD_TURN_ON_LED); //Scrivo su LCD LCD_write_message("Contatore:"); LCD_goto_xy(1,2); LCD_write_message("Premi RESET x 0"); LCD_goto_xy(15,1); LCD_write_char(223); delay_ms(10); //Avvio Seriale UART1_open(UART_BAUDRATE_19200); //Abilito PULL-UP INTCON2bits.RBPU = 0x00; // Abilito le interruzioni su PORTB INTCONbits.RBIE = 1; // Abilito le interruzioni su PORTB come alta priorità INTCON2bits.RBIP = 1; //************************************************************ // Abilito il Timer0 per funzionare a bassa priorità //************************************************************ // Modalità a 8 bit T0CONbits.T08BIT = 1; // Clock interno T0CONbits.T0CS = 0; // Abilito Prescaler T0CONbits.PSA = 0; // Prescaler 256 T0CONbits.T0PS0 = 1; T0CONbits.T0PS1 = 1; T0CONbits.T0PS2 = 1; // Abilito le interruzioni del Timer0 INTCONbits.TMR0IE = 1; // Abilito le interruzioni del Timer0 come bassa priorità INTCON2bits.TMR0IP = 0; // Abilito il Timer0 T0CONbits.TMR0ON = 1; // Abilito modalità interruzione a due livelli RCONbits.IPEN = 1; // Abilito l'interrupt ad alta priorità INTCONbits.GIEH = 1; // Abilito gli interrupt a bassa priorità INTCONbits.GIEL = 1 ; // Resetto il flag d'interrupt prima di attivare le interruzioni INTCONbits.RBIF = 0; // Abilito l'interrupt periferiche INTCONbits.PEIE = 1 ; OldPos = EncoderDT; while(1){ } }

da premettere che sono un autodidatta neofita e il codice potrebbe essere sicuramente migliorato quindi si accettano consigli

anche su questo.

Grazie
Ultima Modifica 5 Anni 1 Mese fa da x206.

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

  • Mauro Laurenti
  • Moderatore
  • Moderatore
Di più
5 Anni 1 Mese fa #2 da Mauro Laurenti
Risposta da Mauro Laurenti al topic Problema con Interrupt
Salve,

per l'interruttore, puoi confermare come è collegato?
Quando dici che non funziona, che verifichi per dire ciò?

Per il problema LCD, le funzioni LCD fanno uso di un Delay bloccante che può creare problemi con le interruzioni.

In particolare dovrebbe funzionare se nel file LTlib_delay.h togli il commento alla linea:

//#define DELAY_INTERRUPT_BLOCKING

o semplicemente definisci

#define DELAY_INTERRUPT_BLOCKING

nel file main prima della tua inclusione

#include "LTlib_delay.h"

Se spulci poi il file LTlib_delay.c puoi vedere cosa cambia.
Proteggo la variabile clock_counter_reference, da chiamate multiple della funzioni delay prima che sia terminato un ritardo.

sebbene dovresti risolvere il problema cerca di togliere le funzioni LCD dall'interrupt service routine. Queste devono rimanere snelle e veloci.
...o potresti ritardare l'esecuzione di altri interrupt.

Saluti,

Mauro

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

  • x206
  • Autore della discussione
  • Giovane Utente
  • Giovane Utente
Di più
5 Anni 1 Mese fa #3 da x206
Risposta da x206 al topic Problema con Interrupt
Salve Mauro,

riguardo l'interruttore era collegato alla porta RB3 la quale non è abilitata all'interrupt correggimi se sbaglio, mentre lo sono

da RB4 a B7, infatti impostando quest'ultima (la RB7) funziona.

Per il problema dello zero sul display ho provato con il DELAY_INTERRUPT_BLOCKING ma non ha funzionato,forse non sono stato

capace io, ho provato sia con la condizione di "if(count == 0)" così com'è scritta nel codice riportato prima e sia

eliminandola, alla fine ho risolto così:
Code:
if(count == 0){ LCD_goto_xy(11,1); LCD_write_message(" "); LCD_goto_xy(14,1); LCD_write_message("0"); } if(count < 0 || count >0){ LCD_goto_xy(11,1); LCD_write_integer(count,4,LCD_ZERO_CLEANING_ON); }

mentre per snellire l'ISR ho fatto come hai detto cioè ho spostato le funzioni LCD nel while(1) ed è migliorata anche la lettura

dell'encoder.

Grazie mille

Luca

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