- Messaggi: 1222
- Ringraziamenti ricevuti 104
verifica del timer1
- StefA
-
Autore della discussione
- Moderatore
-
Less
Di più
12 Anni 8 Mesi fa #1
da StefA
..avevano magari fatto lo sgambetto al ka, ma il sangue restava sempre più denso dell'acqua.. [cit.]
verifica del timer1 è stato creato da StefA
Salve, mi sono ritrovato con qualche dubbio sul timer1 ed in particolare sul suo interrupt.
Ho eseguito la seguente prova (modificando un esempio di Mauro) per cercare di capire meglio..
e funziona come dovrebbe.
Se commento le due righe:
non funziona, e il led 3 cambia stato solo quando premo il pulsante, evidentemente entra nelle routin d'interrupt e trova il flag dell'overflow.
Tutto questo con le interruzioni a due livelli.
commentando e modificando qui e lì si possono vedere i vari casi.. però se metto solamente
// Abilito gli interrupt ad alta priorita'
INTCONbits.GIEH = 1;
non va.
Ho eseguito la seguente prova (modificando un esempio di Mauro) per cercare di capire meglio..
Code:
#include <p18f4550.h>
#include <portb.h>
#pragma config FOSC = HS
#pragma config WDT = OFF
#pragma config LVP = OFF
#pragma config PBADEN = OFF
//OSC = HS Impostato per lavorare ad alta frequenza
//WDT = OFF Disabilito il watchdog timer
//LVP = OFF Disabilito programmazione LVP
//PBADEN = OFF Disabilito gli ingressi analogici
//************************************************************
// Dichiarazione Prototipi di funzione
//************************************************************
// Prototipo di funzione per bassa priorita'
void Low_Int_Event (void);
// Prototipo di funzione per alta priorita'
void High_Int_Event (void);
//************************************************************
// Impostazione e Gestione priorita' alta
//************************************************************
#pragma code high_vector = 0x08
void high_interrupt (void) {
// Salto per la gestione dell'interrupt ad alta priorita'
_asm GOTO High_Int_Event _endasm
}
#pragma code
#pragma interrupt High_Int_Event
// Funzione per la gestione dell'interruzione ad alta priorita'
void High_Int_Event (void)
{
// Indice per il ciclo di pausa
int i;
// Controllo che l'interrupt sia stato generato da PORTB
if (INTCONbits.RBIF == 1 ) {
//pausa filtraggio spike
for (i=0; i<10000; i++){
}
// Controllo la pressione di RB4
if (PORTBbits.RB4 == 0) {
// Accendo il LED 1
LATDbits.LATD1 = ~LATDbits.LATD1;
}
// Resetto il flag d'interrupt per permettere nuove interruzioni
INTCONbits.RBIF = 0;
}
// Appena scatta l'interrupt time1
if (PIR1bits.TMR1IF)
{
// Accendo il LED 3
LATDbits.LATD2 = ~LATDbits.LATD2;
// Azzero il flag di interrupt del timer1
PIR1bits.TMR1IF = 0;
}
}
//************************************************************
// Impostazione e Gestione priorita' bassa
//************************************************************
#pragma code low_vector = 0x18
void low_interrupt (void) {
// Salto per la gestione dell'interrupt a bassa priorita'
_asm GOTO Low_Int_Event _endasm
}
#pragma code
#pragma interruptlow Low_Int_Event
// Funzione per la gestione dell'interruzione ad alta priorita'
void Low_Int_Event (void) {
// Controllo che l'interrupt sia stato generato da Timer0
if (INTCONbits.TMR0IF == 1 ) {
// Inverto lo stato del LED 0
LATDbits.LATD0 = ~LATDbits.LATD0;
// Resetto il flag d'interrupt per permettere nuove interruzioni
INTCONbits.TMR0IF = 0;
}
}
//************************************************************
// Inizio programma principale
//************************************************************
void main (void){
// Variabile usata per creare un conteggio fittizio di pausa
unsigned int i;
// Imposto PORTA tutti ingressi
LATA = 0x00;
TRISA = 0xFF;
// Imposto PORTB tutti ingressi
LATB = 0x00;
TRISB = 0xFF;
// Imposto PORTC tutti ingressi
LATC = 0x00;
TRISC = 0xFF;
// Imposto PORTD tutte uscite
LATD = 0x00;
TRISD = 0x00;
// Imposto PORTE tutti ingressi
LATE = 0x00;
TRISE = 0xFF;
//************************************************************
// Abilito i pulsanti per le interruzioni ad alta priorita'
//************************************************************
// Abilita i resistori di pull-up sulla PORTB
EnablePullups();
// Abilito le interruzioni su PORTB
INTCONbits.RBIE = 1;
// Abilito le interruzioni su PORTB come alta priorita'
INTCON2bits.RBIP = 1;
//************************************************************
// Abilito il Timer0 per funzionare a bassa priorita'
//************************************************************
// Modalita' 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 priorita'
INTCON2bits.TMR0IP = 0;
// Abilito il Timer0
T0CONbits.TMR0ON = 1;
//---> TIMER1
// Imposto la modalità a 16 bit
T1CONbits.RD16 = 1;
// Abilito il clock interno Timer1 (Fosc/4)
T1CONbits.TMR1CS = 0;
// Imposto il PreScaler Timer1 1:2
T1CONbits.T1CKPS0 = 1;
T1CONbits.T1CKPS1 = 1;
// Disabilito l'oscillatore del Timer1
T1CONbits.T1OSCEN = 0;
// Abilito le interruzioni del Timer1
PIE1bits.TMR1IE = 1;
// Abilito le interruzioni del Timer1 ad alta priorità
IPR1bits.TMR1IP = 1;
// Abilito il Timer1
T1CONbits.TMR1ON = 1;
//************************************************************
// Abilito le interruzioni
//************************************************************
// Abilito modalita' interruzione a due livelli alta e bassa
RCONbits.IPEN = 1;
// Abilito gli interrupt ad alta priorita'
INTCONbits.GIEH = 1;
// Abilito gli interrupt a bassa priorita'
INTCONbits.GIEL = 1 ;
// Ciclo infinito
while (1){
}
}
Se commento le due righe:
Code:
// Abilito le interruzioni del Timer1
PIE1bits.TMR1IE = 1;
// Abilito le interruzioni del Timer1 ad alta priorità
IPR1bits.TMR1IP = 1;
Tutto questo con le interruzioni a due livelli.
commentando e modificando qui e lì si possono vedere i vari casi.. però se metto solamente
// Abilito gli interrupt ad alta priorita'
INTCONbits.GIEH = 1;
non va.
..avevano magari fatto lo sgambetto al ka, ma il sangue restava sempre più denso dell'acqua.. [cit.]
Si prega Accesso o Crea un account a partecipare alla conversazione.
- StefA
-
Autore della discussione
- Moderatore
-
Less
Di più
- Messaggi: 1222
- Ringraziamenti ricevuti 104
12 Anni 8 Mesi fa #2
da StefA
..avevano magari fatto lo sgambetto al ka, ma il sangue restava sempre più denso dell'acqua.. [cit.]
Risposta da StefA al topic verifica del timer1
in particolare se ad esempio riguardo l'abilitazione degli interrupt scrivo solamente..
INTCONbits.GIEH = 1;
e non attivo l'interrupt del timer1, come nel programma che segue, si comporta cos':
tutti i led sono spenti, ma se premo uno qualsiasi dei pulsanti della freedom, cambia lo stato del led 3.
Ste
INTCONbits.GIEH = 1;
e non attivo l'interrupt del timer1, come nel programma che segue, si comporta cos':
tutti i led sono spenti, ma se premo uno qualsiasi dei pulsanti della freedom, cambia lo stato del led 3.
Code:
#include <p18f4550.h>
#include <portb.h>
#pragma config FOSC = HS
#pragma config WDT = OFF
#pragma config LVP = OFF
#pragma config PBADEN = OFF
//OSC = HS Impostato per lavorare ad alta frequenza
//WDT = OFF Disabilito il watchdog timer
//LVP = OFF Disabilito programmazione LVP
//PBADEN = OFF Disabilito gli ingressi analogici
//************************************************************
// Dichiarazione Prototipi di funzione
//************************************************************
// Prototipo di funzione per bassa priorita'
void Low_Int_Event (void);
// Prototipo di funzione per alta priorita'
void High_Int_Event (void);
//************************************************************
// Impostazione e Gestione priorita' alta
//************************************************************
#pragma code high_vector = 0x08
void high_interrupt (void) {
// Salto per la gestione dell'interrupt ad alta priorita'
_asm GOTO High_Int_Event _endasm
}
#pragma code
#pragma interrupt High_Int_Event
// Funzione per la gestione dell'interruzione ad alta priorita'
void High_Int_Event (void)
{
// Indice per il ciclo di pausa
int i;
// Controllo che l'interrupt sia stato generato da PORTB
if (INTCONbits.RBIF == 1 ) {
//pausa filtraggio spike
for (i=0; i<10000; i++){
}
// Controllo la pressione di RB4
if (PORTBbits.RB4 == 0) {
// Accendo il LED 1
LATDbits.LATD1 = ~LATDbits.LATD1;
}
// Resetto il flag d'interrupt per permettere nuove interruzioni
INTCONbits.RBIF = 0;
}
// Appena scatta l'interrupt time1
if (PIR1bits.TMR1IF)
{
// Accendo il LED 3
LATDbits.LATD2 = ~LATDbits.LATD2;
// Azzero il flag di interrupt del timer1
PIR1bits.TMR1IF = 0;
}
}
//************************************************************
// Impostazione e Gestione priorita' bassa
//************************************************************
#pragma code low_vector = 0x18
void low_interrupt (void) {
// Salto per la gestione dell'interrupt a bassa priorita'
_asm GOTO Low_Int_Event _endasm
}
#pragma code
#pragma interruptlow Low_Int_Event
// Funzione per la gestione dell'interruzione ad alta priorita'
void Low_Int_Event (void) {
// Controllo che l'interrupt sia stato generato da Timer0
if (INTCONbits.TMR0IF == 1 ) {
// Inverto lo stato del LED 0
LATDbits.LATD0 = ~LATDbits.LATD0;
// Resetto il flag d'interrupt per permettere nuove interruzioni
INTCONbits.TMR0IF = 0;
}
}
//************************************************************
// Inizio programma principale
//************************************************************
void main (void){
// Variabile usata per creare un conteggio fittizio di pausa
unsigned int i;
// Imposto PORTA tutti ingressi
LATA = 0x00;
TRISA = 0xFF;
// Imposto PORTB tutti ingressi
LATB = 0x00;
TRISB = 0xFF;
// Imposto PORTC tutti ingressi
LATC = 0x00;
TRISC = 0xFF;
// Imposto PORTD tutte uscite
LATD = 0x00;
TRISD = 0x00;
// Imposto PORTE tutti ingressi
LATE = 0x00;
TRISE = 0xFF;
//************************************************************
// Abilito i pulsanti per le interruzioni ad alta priorita'
//************************************************************
// Abilita i resistori di pull-up sulla PORTB
EnablePullups();
// Abilito le interruzioni su PORTB
INTCONbits.RBIE = 1;
// Abilito le interruzioni su PORTB come alta priorita'
INTCON2bits.RBIP = 1;
//************************************************************
// Abilito il Timer0 per funzionare a bassa priorita'
//************************************************************
// Modalita' 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 priorita'
// INTCON2bits.TMR0IP = 0;
// Abilito il Timer0
T0CONbits.TMR0ON = 1;
//---> TIMER1
// Imposto la modalità a 16 bit
T1CONbits.RD16 = 1;
// Abilito il clock interno Timer1 (Fosc/4)
T1CONbits.TMR1CS = 0;
// Imposto il PreScaler Timer1 1:2
T1CONbits.T1CKPS0 = 1;
T1CONbits.T1CKPS1 = 1;
// Disabilito l'oscillatore del Timer1
T1CONbits.T1OSCEN = 0;
// Abilito le interruzioni del Timer1
// PIE1bits.TMR1IE = 1;
// Abilito le interruzioni del Timer1 ad alta priorità
// IPR1bits.TMR1IP = 1;
// Abilito il Timer1
T1CONbits.TMR1ON = 1;
//************************************************************
// Abilito le interruzioni
//************************************************************
// Abilito modalita' interruzione a due livelli alta e bassa
// RCONbits.IPEN = 1;
// Abilito gli interrupt ad alta priorita'
// INTCONbits.GIEH = 1;
// Abilito gli interrupt a bassa priorita'
// INTCONbits.GIEL = 1 ;
// 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 ;
INTCONbits.GIEH = 1;
// Ciclo infinito
while (1){
}
}
Ste
..avevano magari fatto lo sgambetto al ka, ma il sangue restava sempre più denso dell'acqua.. [cit.]
Si prega Accesso o Crea un account a partecipare alla conversazione.
- Pinna
-
- Moderatore
-
Less
Di più
- Messaggi: 1010
- Ringraziamenti ricevuti 107
12 Anni 8 Mesi fa - 12 Anni 8 Mesi fa #3
da Pinna
Chi vola vale, chi vale vola, chi non vola è un vile
Risposta da Pinna al topic verifica del timer1
Stefano, guarda queste impostazioni:
// Imposto il PreScaler Timer1 1:2
T1CONbits.T1CKPS0 = 1;
T1CONbits.T1CKPS1 = 1;
non è impostato 1.2 ma 1.8 (a meno che non l'abbia impostato tu in questo modo volontariamente)
Marcello
p.s. domani ti seguo con le prove, ora purtroppo devo chiudere: è arrivata gente in casa. Fammi sapere
// Imposto il PreScaler Timer1 1:2
T1CONbits.T1CKPS0 = 1;
T1CONbits.T1CKPS1 = 1;
non è impostato 1.2 ma 1.8 (a meno che non l'abbia impostato tu in questo modo volontariamente)
Marcello
p.s. domani ti seguo con le prove, ora purtroppo devo chiudere: è arrivata gente in casa. Fammi sapere
Chi vola vale, chi vale vola, chi non vola è un vile
Ultima Modifica 12 Anni 8 Mesi fa da Pinna.
Si prega Accesso o Crea un account a partecipare alla conversazione.
- StefA
-
Autore della discussione
- Moderatore
-
Less
Di più
- Messaggi: 1222
- Ringraziamenti ricevuti 104
12 Anni 8 Mesi fa #4
da StefA
..avevano magari fatto lo sgambetto al ka, ma il sangue restava sempre più denso dell'acqua.. [cit.]
Risposta da StefA al topic verifica del timer1
si, è volontario così il led 3 lampeggia più lentamente e si vede meglio.. 
Buona cena!
Ste
Buona cena!
Ste
..avevano magari fatto lo sgambetto al ka, ma il sangue restava sempre più denso dell'acqua.. [cit.]
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.
