Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Timer0 Interrupt in PIC

Status
Not open for further replies.

scorrpeio

Full Member level 5
Joined
Dec 26, 2006
Messages
286
Helped
10
Reputation
20
Reaction score
9
Trophy points
1,298
Activity points
3,496
Hi...

I have written code for timer0 in which everytime TMR0 overflows...it plays buzzer.

However, I didnt use ISR. I used this...
Code:
void EnableTimer (void)
{	
	unsigned int Cnt_15min = 2;
	TRISCbits.TRISC2 = 0; 	//Set BUZZER pin as o/p pin
	PORTCbits.RC2 	 = 0;	// Keep BUZZER OFF
	TMR0L = 0x00;
	T0CON = 0x07;  	// prescalar of 1:256; internal clock; 16 bit mode
			  		// Timer disabled

//	INTCONbits.GIE = 1; //Enable Global Interrupt			  
//	INTCONbits.TMR0IE = 1;//Enable Timer0 Interrupt

	while( Cnt_15min )
	{ 
		T0CONbits.TMR0ON = 1; //Start Timer0	

		while (INTCONbits.TMR0IF == 0 );
		{		
//			PORTB = 0b00000000;
			INTCONbits.TMR0IF = 0;
		}
		Cnt_15min--;
		T0CONbits.TMR0ON = 0; //Disable Timer
	}
	PORTCbits.RC2 = 1; //BUZZER ON	

	PORTCbits.RC2 = 0;
	GetTemperatureValue();
}

This is working fine.

However, I want to achieve same, using Timer Interrupt.
I tried with this...

Code:
#pragma code low_vector = 0x18
void high_ISR (void)
{
_asm goto timer0_isr _endasm
}
#pragma code

#pragma interrupt timer0_isr

void timer0_isr(void)
{
	INTCONbits.TMR0IE = 0; //Disable Timer 0 Interrupt
	INTCONbits.TMR0IF = 0; //Clear Timer 0 Interrupt Flag
	PORTB = 0b00000000;
}

I had activated the Global and TIMER0 inetrrupts. But, execution never went into isr loop. I have never used isr in pic. I guess, I could not write it properly. Can anyone let me know, why does it not work? (I have gone through different threads on this site to write the above routine.)
 

You should enable ( = 1 ) TMR0IE outside the interrupt routine but you shouldn't change it inside the routine. All you should do is reset the interrupt flag TMR0IF, leave the TMR0IE enabled all the time.
It looks like you are using a PIC18 processor, make sure you have TMR0 assigned to low priority or the low interrupt vector will not be called.
 
Hi...
thnx for the reply.

I have done the changes you suggested, but still it doesnt work :sad:
I am using pic 18F4520
This is the modified code...

Code:
void EnableTimer (void)
{	
	unsigned int Cnt_15min = 2;
	BUZZER_ACTIVATE  = 0; 	//Set BUZZER pin as o/p pin
	BUZZER 			 = 0;	// Keep BUZZER OFF
	
	TMR0L = 0x00;
	T0CON = 0x07;  	// prescalar of 1:256; internal clock; 16 bit mode
			  		// Timer disabled
			  		
	RCONbits.IPEN 		= 1;	//Enable Interrupt Priorities
	INTCONbits.GIEL 	= 1; 	//Enable Low Priority Interrupt
	INTCON2bits.TMR0IP	= 0;	//TMR0 set to Low Priority Interrupt
	INTCONbits.GIE 		= 1; 	//Enable GlobalInterrupt			  
	INTCONbits.TMR0IE 	= 1;	//Enable Timer0 Interrupt
	
	PORTBbits.RB1 = 1;


	T0CONbits.TMR0ON = 1; //Start Timer0

//This works fine...now chek why ISR doesnt work
//	while( Cnt_15min )
//	{ 
//		T0CONbits.TMR0ON = 1; //Start Timer0	
//
//		while (INTCONbits.TMR0IF == 0 );
//		{		
//			INTCONbits.TMR0IF = 0;
//		}
//		Cnt_15min--;
//		T0CONbits.TMR0ON = 0; //Disable Timer
//	}
//	
//	BUZZER = 1; //BUZZER ON	
//	Delay(20);	
//	BUZZER = 0; //BUZZER OFF	
//	GetTemperatureValue();
}

#pragma code low_vector = 0x18
void high_ISR (void)
{
_asm goto timer0_isr _endasm
}
#pragma code

#pragma interrupt timer0_isr

void timer0_isr(void)
{
	T0CONbits.TMR0ON  	= 1; 	//Disable Timer0
	INTCONbits.TMR0IF 	= 0;  //Clear Timer 0 Interrupt Flag
	
	PORTBbits.RB1 		= 0;
	
	BUZZER = 1; //BUZZER ON	
	Delay(20);	
	BUZZER = 0; //BUZZER OFF
	
}
 

Try using following piece of code, its working in my case
make changes, if required, as shown in InitDevice routine, or copy paste as it is...
Please, Let me know the result...

void timer_isr (void);

void InitDevice (void)
{
RCON |= 0b10000000; // enable interrupt priority
INTCON |= 0b11100000; // enable high & low priority interrupt
INTCON2 &= 0b11111011; // assign low priority to timer0 interrupt
}


#pragma code low_vector=0x18
void low_interrupt (void)
{
_asm GOTO timer_isr _endasm
}
#pragma code

#pragma interruptlow timer_isr
void timer_isr (void)
{
if(INTCONbits.TMR0IF) // if timer0 overflow interrupt occurs
{
INTCONbits.TMR0IF = 0; // clear overflow flag

// your stuff
PORTBbits.RB1 = 0;

BUZZER = 1; //BUZZER ON
Delay(20);
BUZZER = 0; //BUZZER OFF

}
}


__
Amit
** If you find my answer useful, please click the "Helpful? Please click" icon. **
 
Your second while() loop, the one looking for the TMR0IF bit looks wrong, you check if it's zero and if it is, you set it to zero again.

Forget that, I didn't spot the semicolon after the while() !
It is still structured wrongly though. Do you really want to put a delay inside a timer ISR? If the delay is longer than the interrupt rate you will almost certainly run into problems. Normally, you want to get out of an ISR as quickly as possible as it blocks other interrupts until you leave. A better solution would be to set a flag inside the ISR and check if it is set in your main() routine.
 
Last edited:
sir, tht code is commented...

the code which is in action is...
Code:
void EnableTimer (void)
{	
	unsigned int Cnt_15min = 2;
	BUZZER_ACTIVATE  = 0; 	//Set BUZZER pin as o/p pin
	BUZZER 			 = 0;	// Keep BUZZER OFF
	
	TMR0L = 0x00;
	T0CON = 0x07;  	// prescalar of 1:256; internal clock; 16 bit mode
			  		// Timer disabled
			  		
	RCONbits.IPEN 		= 1;	//Enable Interrupt Priorities
	INTCONbits.GIEL 	= 1; 	//Enable Low Priority Interrupt
	INTCONbits.GIE 		= 1; 	//Enable GlobalInterrupt			  
	INTCONbits.TMR0IE 	= 1;	//Enable Timer0 Interrupt
	INTCON2bits.TMR0IP	= 0;	//TMR0 set to Low Priority Interrupt
	
	PORTBbits.RB1 = 1;

	T0CONbits.TMR0ON = 1; //Start Timer0
}


#pragma code low_vector = 0x18
void low_ISR (void)
{
_asm goto timer0_isr _endasm
}
#pragma code

#pragma interruptlow timer0_isr

void timer0_isr(void)
{
	T0CONbits.TMR0ON  	= 1; 	//Disable Timer0
	INTCONbits.TMR0IF 	= 0;  //Clear Timer 0 Interrupt Flag
	
	PORTBbits.RB1 		= 0;  //Turn OFF LED
	
			
}

I have corrected the mistakes you pointed.
But, the problem is, execution doesnt enter into the ISR routine. :sad:

---------- Post added at 13:43 ---------- Previous post was at 13:30 ----------

Hello,
It is working...
The problem was not with this routine. The problem was in main(), I have resolved it.
The above routine is working fine.
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top