Timer0 e interrupt

  • marcoilgrande
  • Autore della discussione
  • Giovane Utente
  • Giovane Utente
Di più
1 Mese 1 Settimana fa #1 da marcoilgrande
Timer0 e interrupt è stato creato da marcoilgrande
Ciao a tutti,
Ho bisogno di un aiuto, sto impazzendo perchè non riesco a configurare le interruzioni come voglio, nel senso che vorrei fare in modo che la 232 generi un interrupt priorità alta mentre il timer0 generi un interrupt priorità bassa.

Il codice è questo, inizialmente pare funzionare poi dopo qualche carattere ricevuto impazzisce tutto.




// Resetto gli Interrupt vecchi
PIR1bits.RC1IF = 0;
//Abilito Interruzione UART1
//PIE1bits.TX1IE = 1;//non va timer0
PIE1bits.RC1IE =1; //mah
// Abilito modalità compatibile (di default vale già 0)
RCONbits.IPEN = 0;
// Abilito l'interrupt globale
INTCONbits.GIE = 1;
// Abilito interrupt per periferiche
INTCONbits.PEIE = 1;
// Ciclo infinito


//************************************************************
// Abilito il Timer0 per funzionare a bassa priorità
//************************************************************
// Modalità a 16 bit
T0CONbits.T08BIT = 0;
// Clock interno
T0CONbits.T0CS = 0;
// Abilito Prescaler
T0CONbits.PSA = 0;
// Prescaler 32
T0CONbits.T0PS0 = 0;
T0CONbits.T0PS1 = 0;
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 le interruzioni
//************************************************************
// Abilito modalità interruzione a due livelli alta e bassa
RCONbits.IPEN = 1;
// Abilito gli interrupt ad alta priorità
INTCONbits.GIEH = 1;
// Abilito gli interrupt a bassa priorità
INTCONbits.GIEL = 1 ;


interruzioni
//*************************************************
// Gestione Interrupt
//*************************************************
__interrupt (high_priority) void ISR_alta (void) {
// Variabile che conterrà i dati ricevuti
unsigned char data;
// Flag per controllare la ricezione del primo carattere
static unsigned char firstTime = 0;

// Controllo che l'interrupt sia stato generato dall'USART
if (PIR1bits.RC1IF == 1) {
// Resetto gli Interrupt EUSART
PIR1bits.RC1IF = 0;
// Controllo la ricezione del primo carattere
if (firstTime == 0) {
LCD_clear ();
// Memorizzo il fatto che ho già pulito il display
firstTime = 1;
}
// Leggo il dato dal buffer di ricezione
data = UART_read_byte();
LCD_write_char (data);
// Invio il carattere al terminale
UART_write_byte (data);
// Attendo che il dato venga trasmesso
while (UART_TX_busy());
// Se premo Back Space pulisco lo schermo
if(data == 0x08) {
LCD_clear ();
}
// Se premo Esc termino l'applicazione
if(data == 0x1B) {
LCD_clear ();
// Chiudo l'USART
UART_close();
// Ripulisco LCD prima di riscrivere
LCD_clear ();
// L'USART è stata chiusa
LCD_write_message ("RS232 : Closed");
// Disabilito l'interrupt globale
INTCONbits.GIE = 0;
}
}
}


//*************************************
// ISR Bassa Priorita'
//*************************************
__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 per permettere nuove interruzioni
INTCONbits.TMR0IF = 0;
// Inverto lo stato del LED 0
LCD_goto_xy (1,4);
LCD_write_message ("   conto:");
LCD_write_integer (cicl,5,0);
cicl++;
}

}

grazie a chiunque per il suo aiuto
 

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

  • Mauro Laurenti
  • Moderatore
  • Moderatore
Di più
3 Settimane 4 Ore fa #2 da Mauro Laurenti
Risposta da Mauro Laurenti al topic Timer0 e interrupt
Salve Marco,

il problema principale credo che sia dovuto al fatto che usi la libreria LCD all'interno degli ISR.

La libreria LCD fa uso di delay bloccanti, ed è relativamente lenta.
Ogni aggiornamento del display deve essere fatto fuori dall'ISR.

Questo lo si ottiene spesso implementando delle macchine a stati.
Nell'ISR cambi solo lo stato e fuori dall'ISR controlli lo stato ed effettui gli aggiornamenti del display.

Il testo XC8 Step by Step ha degli esempi con state machine

Nell'ISR, come regola generale, non usare le funzioni delay

Saluti,

Mauro 

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