Jump to content
PLC Forum


Sign in to follow this  
Tecnica Impianti

Interrupt Su Timer0

Recommended Posts

Tecnica Impianti

Buongiorno a tutti, mi sto cimentando ad usare gli interrupt sul timer0 per ottenere il classico lampeggio di un led.

ho provato in diversi modi ma senza successo anzi con un modo ha funzionato ma invece di farmi lampeggiare un solo led me li faceva lampeggiare tutti.

Mi era bastato aggiungere ai config iniziale PLLDIV=2 ma veniva fuori un casino.... vi posto il codice cosi magari mi dite dove sbaglio.

Grazie...


#include <p18f2550.h>

#include <delays.h>

#pragma config FOSC = HSPLL_HS

#pragma config IESO= ON

#pragma config WDT = OFF

#pragma config LVP = OFF

#pragma config PBADEN = OFF


//OSC = HSPLL_HS Impostato per lavorare ad alta frequenza CON PLL ATTIVATO

//PLL = attivato la divisione

//WDT = OFF Disabilito il watchdog timer

//LVP = OFF Disabilito programmazione LVP

//PBADEN = OFF Disabilito gli ingressi analogici

//PLLDIV1= divisione PLL

//Impostazione per bassa priorità

void Low_Int_Event (void);

#pragma code low_vector=0x18

void low_interrupt (void){

//salto per la gestione dell'interrupt a bassa priorità

_asm GOTO Low_Int_Event _endasm;

}

#pragma code

#pragma interruptlow Low_Int_Event

//Funzione per la gestione dell'interrupt a bassa priorità

void Low_Int_Event (void){

// controllo che l'interrupt sia stato generato dal timer0

if(INTCONbits.TMR0IF==1){

PORTBbits.RB2=~PORTBbits.RB2;

INTCONbits.TMR0IF=0;

}

}


void main (void){

//Abilitazione oscilatore interno

OSCTUNEbits.INTSRC=1;

OSCTUNEbits.TUN4=0;

OSCTUNEbits.TUN3=1;

OSCTUNEbits.TUN2=1;

OSCTUNEbits.TUN1=1;

OSCTUNEbits.TUN0=1;

OSCCONbits.IRCF2=0;

OSCCONbits.IRCF1=0;

OSCCONbits.IRCF0=1;

OSCCONbits.IOFS=1;

OSCCONbits.SCS1=0;

OSCCONbits.SCS0=0;

//Abilitazione TIMER0

T0CONbits.TMR0ON=1; //abilito il timer0

T0CONbits.T08BIT=0; // lo configuro a 16 bit

T0CONbits.T0CS=0; //clock interno

T0CONbits.T0SE=0;

T0CONbits.PSA=0; // assegno il prescaler al timer0

T0CONbits.T0PS2=1; //valore di prescaler 1:32

T0CONbits.T0PS1=1; //valore di prescaler 1:32

T0CONbits.T0PS0=1; //valore di prescaler 1:32

TMR0L=01100111; // sistema abilitato a bassa priorità

TMR0H=01101001; // sistema non abilitato all'alta priorità

INTCONbits.TMR0IE=1; //interruzioni abilitate

INTCONbits.TMR0IF=1; // abilito la visualizzazione dell'evento sul timer1

INTCON2bits.TMR0IP=0; // abilito per bassa priorità

// Imposto PORTA tutti ingressi

TRISA = 0b11111111;

ADCON1= 0b11111111;//Imposto come 1/0 tutti i pin del lato A, avrei potuto anche impostarne uno solo.

// Imposto PORTB tutti ingressi

TRISB = 0b11111000;

// Imposto PORTC tutti ingressi

TRISC = 0b11111111;

//Dico al Pin RA0 che il suo stato se premuto è uguale a 1 cosi il Pin del LED RB0 si attiva

if(PORTAbits.RA0==1){

PORTBbits.RB0=0;

}

else {PORTBbits.RB0=1;

}

if(PORTAbits.RA1==1){

PORTBbits.RB1=0;

}

else{PORTBbits.RB1=1;}


while (1){

}

}

Share this post


Link to post
Share on other sites

Livio Orsini

  1. Il LED che vuoi accendere dove è collegato? Perchè dai commenti del listato si capisce poco
  2. Il LED vuoi che lampeggi dopo aver premuto il tasto?

Share this post


Link to post
Share on other sites
Tecnica Impianti

Ciao e grazie... no il led è su RB2 volevo che lampeggiasse su overflow del timer0......

e sarebbe questa parte:


//Impostazione per bassa priorità

void Low_Int_Event (void);

#pragma code low_vector=0x18

void low_interrupt (void){

//salto per la gestione dell'interrupt a bassa priorità

_asm GOTO Low_Int_Event _endasm;

}

#pragma code

#pragma interruptlow Low_Int_Event

//Funzione per la gestione dell'interrupt a bassa priorità

void Low_Int_Event (void){

// controllo che l'interrupt sia stato generato dal timer0

if(INTCONbits.TMR0IF==1){

PORTBbits.RB2=0;

PORTBbits.RB2=1;

INTCONbits.TMR0IF=0;

}

}

Come si capisce poco???? ho anche messo tutti i commenti!!!!!

Share this post


Link to post
Share on other sites
GiRock

Errori grossolani, configurazioni sparate a caso etc. etc...

Dichiari un oscillatore a 20Mhz e poi utilizzi quello interno!!!

Imposti la PORTA abilitando l'ADC analogico e poi lo utilizzi come ingresso digitale!!!

Tutti gli ingressi analogici vanno disabilitati se non utilizzati compresi i comparatori!!!

Se configurati come ingressi i pin non connessi o senza abilitare le pull-up vanno collegati da qualche parte!!!

La regola impone che i pin liberi siano uscite per non avere effetti indesiderati!!!

Non vedo GIE nel codice, Global Interrupt Enable!!!

Prima si configura il Timer poi lo si abilita, è inutile usare un 16bit per far lampeggiare un LED separando addirittura TMR0H da TMR0L con due priorità diverse (inesistente), quelli servono ad immagazzinare il valore del tempo trascorso con un preload per avvicinarsi alla precisione voluta!!!

Mancherebbe pure la funzione antirimbalzo per il pulsante volendo!!!

Ma cosa più grave, stai ciclando il nulla, le istruzioni condizionali sono esterne ed inutili a mio avviso, e a tutta manetta!!!

Il PIC che hai usato ha anche altre peculiarità che andranno settate opportunamente, pena la imprevedibilità del risultato, forse è meglio che ti rileggi il datasheet da capo...

P.S. Probabilmente mi è sfuggito qualcosa, ma già a metà ne avevo viste troppe, come consigliato insisti e studiati meglio il tutto...

Share this post


Link to post
Share on other sites
Livio Orsini
Come si capisce poco???? ho anche messo tutti i commenti!!!!!

peccato che alcuni sembran messi li alla....pene di molosso. :smile:

Io non uso quel compilatore (usco CCS), ma mi sembra che hai scritto un po' troppo solo per far lampeggiare un led; 10 righe dovrebbero esser più che sufficienti.

Segui i consigli di nonik e di girock.

Share this post


Link to post
Share on other sites
Tecnica Impianti

ok allora mi rileggo il datasheet anche se mi sembra che per le impostazioni del timer0 e degli interrupt dovevo necessariamente abilitare tutte quelle cose....

ci riproverò....

Grazie

Share this post


Link to post
Share on other sites
Tecnica Impianti

Ok come da vostro consiglio mi sono riletto per l'ennesima volta il datasheet delle parti che mi interessavano.

ebbene si ora funziona come dovrebbe....

Grazie ancora....


#include <p18f2550.h>

#include <delays.h>

#include <timers.h>

#pragma config FOSC = HSPLL_HS

#pragma config IESO= ON

#pragma config WDT = OFF

#pragma config LVP = OFF

#pragma config PBADEN = OFF


//OSC = HSPLL_HS Impostato per lavorare ad alta frequenza CON PLL ATTIVATO

//PLL = attivato la divisione

//WDT = OFF Disabilito il watchdog timer

//LVP = OFF Disabilito programmazione LVP

//PBADEN = OFF Disabilito gli ingressi analogici


//Impostazione per bassa priorità


void Low_Int_Event (void);

#pragma code low_vector=0x18

void low_interrupt (void){

//salto per la gestione dell'interrupt a bassa priorità

_asm GOTO Low_Int_Event _endasm;

}


#pragma code

#pragma interruptlow Low_Int_Event


//Funzione per la gestione dell'interrupt a bassa priorità

void Low_Int_Event (void){


// controllo che l'interrupt sia stato generato dal timer0

if(INTCONbits.TMR0IF==1){


PORTBbits.RB2=~PORTBbits.RB2;  // Faccio lampeggiare il led


INTCONbits.TMR0IF=0; // Riporto a zero il timer

}

}


void main (void){


//Abilitazione TIMER0

T0CONbits.TMR0ON=1; //abilito il timer0

T0CONbits.T08BIT=1; // lo configuro a 8 bit

T0CONbits.T0CS=0; //clock interno

T0CONbits.PSA=0; // assegno il prescaler al timer0

T0CONbits.T0PS2=1; //valore di prescaler 1:32

T0CONbits.T0PS1=1; //valore di prescaler 1:32

T0CONbits.T0PS0=1; //valore di prescaler 1:32


// Abilito l'interrupt

INTCONbits.TMR0IE=1; //interruzioni abilitate

INTCONbits.GIE=1; //Interrupt globali

INTCONbits.PEIE=1;//Interrupt a bassa priorità

INTCON2bits.TMR0IP=0;//Bassa priorità

RCONbits.IPEN=1; //Interrupt priorità abilitato


// Imposto PORTA tutti ingressi

TRISA = 0b11111111;


ADCON1= 0b11111111;//Imposto come 1/0 tutti i pin del lato A, avrei potuto anche impostarne uno solo.


// Imposto PORTB tutti ingressi

TRISB = 0b11111000;


// Imposto PORTC tutti ingressi

TRISC = 0b11111111;


//Dico al Pin RA0 che il suo stato se premuto è uguale a 1 cosi il Pin del LED RB0 si attiva

if(PORTAbits.RA0==1){

PORTBbits.RB0=0;

}

else {PORTBbits.RB0=1;

}


if(PORTAbits.RA1==1){

PORTBbits.RB1=0;

}

else{PORTBbits.RB1=1;}


while (1){

}

}

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this  

×
×
  • Create New...