- Messaggi: 30
- Ringraziamenti ricevuti 0
Problema con Interrupt
- x206
-
Autore della discussione
- Giovane Utente
-
Less
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:
da premettere che sono un autodidatta neofita e il codice potrebbe essere sicuramente migliorato quindi si accettano consigli
anche su questo.
Grazie
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.
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
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
-
Less
Di più
- Messaggi: 30
- Ringraziamenti ricevuti 0
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ì:
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
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 Laurenti, Pinna, StefA, Matteo Garia
Registrati al sito
Accedi a tutte le risorse e articoli non visibili pubblicamente, puoi registrarti con pochi passi.
Forum - Ultimi messaggi
-
- progetto can
- da marcelloraja
-
- MODULO GSM SIM900A
- da Mauro Laurenti
-
- Freedom III e compilazioni fallite
- da Mauro Laurenti
-
- Gestione degli errori su comunicazione seriale
- da Mauro Laurenti
-
- Timer0 e interrupt
- da Mauro Laurenti