Interrupt routine problem.

Go To Last Post
18 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi, I'm having a problem with an interrupt routine. the ISR is executed with the rising edge of INT0 which is connected to a push button.

The problem is, that I have to use the push button within the ISR for some other functions. But as soon as I press the the button inside the ISR, the interrupt is executed again and the ISR is reentered. (I proved this with a counter value shown on my LCD.

cli does'nt work at the beginning of the ISR.

Does anybody has any idea how I can disable external interrupts while I'm inside the ISR ?

Thanks in advance, Harald.

interrupt [EXT_INT0] void ext_int0_isr(void)
{
char strinterrupt[6] ;

#asm("cli")            

intcnt++ ;
sprintf(strinterrupt,"%d",intcnt) ;


	delay_ms(100) ;           
	if ( PIND.2 == 1 )
	{	
		while ( PIND.2 == 1 ) {}; 			}
	
 	while ( PIND.2 == 0 )                           
	{
        lcd_clear() ;          
        lcd_gotoxy(0,1); 
        lcd_puts(strinterrupt) ;
	note(C2,T8,T10);  	// C                  
	note(E2,T8,T10); 	// E                  
	note(G2,T8,T10); 	// G                  
	note(C2,T8,T10);   	// A 	                  
 	
 	delay_ms(500) ;

	note(C3,T8,T10);  	// C                  
	note(E3,T8,T10); 	// E                  
	note(G3,T8,T10); 	// G                  
	note(C2,T4,T10);   	// A 	                  

 	delay_ms(500) ;	     
 	
 	}  
 	          
	while ( PIND.2 == 1 )                           
	{
		delay_ms(10) ;
	} ; 	                  
 	sleepcnt=0 ;      

#asm("cli")  
#asm("sei")				                                 
}
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

When the interrupt function is left the micro (in hardware) re-enables the main interrupt. You will have to disable the INT0 option.

Keep it simple it will not bite as hard

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Use SIGNAL instead of INTERRUPT, this will disable other interrupts form happening while in the handeler.

I will add, that if your interrupt handeler is running and expecting further user input, then you really need to re-architect your application... interrupt handelers should run as short as possible.

Writing code is like having sex.... make one little mistake, and you're supporting it for life.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

thanks, I thought about disabling the INT0 option, but how ?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

blueled wrote:
thanks, I thought about disabling the INT0 option, but how ?

hmmm... how about clearing it's corresponding bit in the EIMSK register. Basically the opposite of what you did to enable it in the first place.

Writing code is like having sex.... make one little mistake, and you're supporting it for life.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
Use SIGNAL instead of INTERRUPT

?!? CV AVR...

Hey, BlueLED... just clear the EXT_INT0 interrupt flag prior to exit the ISR.

Real men don't use backups, they post their stuff on a public ftp server and let the rest of the world make copies.

Last Edited: Mon. Jul 4, 2005 - 08:14 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

groenhen wrote:
Quote:
Use SIGNAL instead of INTERRUPT

?!?

Sorry, my mistake, I missed the code. I saw it as the GCC INTERRUPT, and not as interrupt[]. in GCC INTERRUPT leaves the interrupt handler interruptible by other interrupt sources, including the same source. Using SIGNAL (in GCC) would solve this.

Writing code is like having sex.... make one little mistake, and you're supporting it for life.

Last Edited: Mon. Jul 4, 2005 - 08:30 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

@ glitch
thanks anyway I could say that I was not using GCC.
I'm using CV.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi glitch!
So, SIGNAL (in GCC) means that ISR is non-interruptable ?
Or: SIGNAL means that ISR may be interrupted by other interrupt (except the same source) ?
I'm asking 'cause I don't know gcc, but it sounds interesting...

Real men don't use backups, they post their stuff on a public ftp server and let the rest of the world make copies.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Sorry...
G-zus, it takes 3 - 5 min. to load/reload a page on avrfreaks... :(

Real men don't use backups, they post their stuff on a public ftp server and let the rest of the world make copies.

Last Edited: Mon. Jul 4, 2005 - 08:31 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

blueled wrote:
@ glitch
thanks anyway I could say that I was not using GCC.
I'm using CV.

Yeah I see that now. At any rate, clearing the interrupts' bit in EIMSK will disable that interrupt source. But I still maintain that you should re-visit your program design, as you are spending far too much time inside of the interrupt handler. The moment you start putting printf()'s, delays or other output/delay primitives into your service routine, you should realize that you're heading down the wrong path. Continuing to do so, could result in your program becoming sluggish, or even unresponsive altogether.

Writing code is like having sex.... make one little mistake, and you're supporting it for life.

Last Edited: Mon. Jul 4, 2005 - 08:30 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

groenhen wrote:
Hi glitch!
So, SIGNAL (in GCC) means that ISR is non-interruptable ?
Or: SIGNAL means that ISR may be interrupted by other interrupt (except the same source) ?
I'm asking 'cause I don't know gcc, but this sounds interesting...

SIGNAL means that the handler is non-interruptible by any source (global interrupts are disabled)

INTERRUPT means that the handler will be interruptible by any source (global interrupts enabled)

Writing code is like having sex.... make one little mistake, and you're supporting it for life.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

@glitch

Thanks for that advice glitch, I allready started to rearrange the ISR, you're right and I think I found a solution that will work for me.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

BTW: about ... I was referring to the interrupt flag bit (in EIFR or something).

Real men don't use backups, they post their stuff on a public ftp server and let the rest of the world make copies.

Last Edited: Mon. Jul 4, 2005 - 09:20 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
can disable external interrupts while I'm inside the ISR ?

The ints are disabled when inside the ISR. Just when yu press the button the flag of the ext int is set and when you exit the ISR and the global ints are enabled again the new int is executed.I agree with Stanley. Clear the int bit when exiting.
Kostas

It's better to keep your mouth shut and think you a fool, than open it and move out the doubts!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

groenhen wrote:
BTW: about ... I was referring to the interrupt flag bit (in EIFR or something).

Clearing the flag will not help, as if it gets set again before your routine is done, the routine will be called once again... you need to disable the interrupt through it's mask register instead.

Writing code is like having sex.... make one little mistake, and you're supporting it for life.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks again, now it's working.
I've cleared the bit before leaving ISR and it works perfect.

Have a good night,

Harald.

Sometimes, when your mind is stuck somewhere, you need a hint from someone else. :-)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

glitch wrote:
Clearing the flag will not help, as if it gets set again before your routine is done, the routine will be called once again... you need to disable the interrupt through it's mask register instead.

No, no! I already mentioned: ... clearing the flag just before exiting the ISR!

G-zus! 23:30 ... I must go to "sleep mode" now! :lol:

Real men don't use backups, they post their stuff on a public ftp server and let the rest of the world make copies.