Problem with interrupt Please help

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

Hi folks

I was forced to write an another post.
Problem really drives me crazy. :evil:

It concerns external interrupt.
To be more precise I use INT0 on my atmega8 and it reacts at "The falling edge of INT0 generates an interrupt request".

Generally I want to switch between 4 modes in my program that`s why I`m incrementing mode register.
In this way I want to switch between modes.

mode0,mode1,mode2,mode0,mode1,mode2....

Problem is that when I push buttom diodes which are indicating which mode is being used are driving crazy.

I know about bouncing effect so I used SR latch to assure debouncing. That has not helped so I made SR latch on two NAND gates and it also hasn`t brought any success. (In guide for debouncing it is said that it`s the best method :/ ) :cry:

Code to the interrupt request:


ISR(INT0_vect)
{

mode_register=(mode_register+1); //move mode_register
if(mode_register>3)
	{
		mode_register=0;
	}
clear_PWMs();
}

Well my suspicion is that some oscillations can occur on the ground cause I am using 3 OCR to control 3 PWMs. So maybe it is good idea to change to the mode "the rising edge of INT0 generates an interrupt request "

I have a strange feeling that when I use PWMs with interrupts I can`t manage with interrupts.

Oh and another thing I have an old oscilloscope so I am not able to measure bouncings.

I belive that you will help with this problem!

I am Looking forward to your solutions.

Adam

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

Are you sure that you did not configure the interrupt for "low level"?

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

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

That`s mainly waht I do with interrupt:

GICR|=(1<<INT0);
MCUCR|=(1<<ISC11);

Obviously then

sei();

Hmm still dont have an idea what to do ...

Adam

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

This:
MCUCR|=(1<<ISC01);
is for interrupt 0 (INT0).

Your:
MCUCR|=(1<<ISC11);
is for interrupt 1 (INT1).

Lee is correct. Your INT0 is configured as a low level interrupt.

Last Edited: Mon. Sep 10, 2007 - 08:11 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Using external interrupt for button reading like that is bad, but I have to give credits for the SR latch and the other hardware debounce idea. May you post the schematics? At least I would disable the button interrupt for a while (10ms maybe) before enabling it again. You would need a timer or main loop counter for that, maybe.

But in any case, I would suggest that you use a periodic timer interrupt to poll the button pin, and do the debounce in software. For example, 1ms timer interrupt, and if the filtered button state is "off", then flip the filtered button state to "on" only if the physical button state is on for 20 consecutive pollings, otherwise reset the counter to 0. Same hysteresis might be handy for button release too - 20 continuous counts of off state before your filtered button is set to off.

It is not even necessary to use a timer interrupt to poll the button, you can just poll the button in main loop, just read it every nth loop or increase the maximum count to something which takes 5-20ms to detect the button is pressed.

- Jani

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

Hello again folks :)

Mike B was right I made a stupid mistake.
But I also considered what Jani said and I have decided to make a software debouncer.
I am using 1Mhz internal clock.

I am using timer0 interrupt:

Please help me:

Below I am enclosing code:


//Timer0
TCCR0|=(1<<CS01);
TIMSK|=(1<<TOIE0);

unsigned char DebouncedKeyPress = 0x00;
unsigned char poprzedni=0x00;

unsigned char RawKeyPressed(void) //function for reading PB0
{
	unsigned char value=0;
	
	
	if ((PINB & (1 << PB0)) == 0)   // checks if PIND0 is pressed
	{
		value=1;
	}
	else value=0;
	
	return value;

void DebounceSwitch1(unsigned char *Key_changed, unsigned char *Key_pressed)
{
	static unsigned int Count= RELEASE_MSEC / CHECK_MSEC;
	unsigned char RawState;
	*Key_changed = 0x00;
	*Key_pressed = DebouncedKeyPress;
	RawState = RawKeyPressed();
	
	if (RawState == DebouncedKeyPress)
		{
				//setting the timer for initial value here:
					TCNT0=0x00; //rozna wartosc dostosowana dokladnie do czasu
				if (DebouncedKeyPress)  Count = RELEASE_MSEC / CHECK_MSEC;
				
				else				   Count = PRESS_MSEC / CHECK_MSEC;
			
		}
	else
		{
			//Key has changed - wait for new state to become stable
			if (--Count == 0)
			{
					//Counter expired - accept the change.
					DebouncedKeyPress = RawState;
					*Key_changed = 0x01;
					*Key_pressed = DebouncedKeyPress;
					TCCR0=0x00;    //Now we are reseting the Timer to the desired value
					
					if (DebouncedKeyPress)  Count = RELEASE_MSEC / CHECK_MSEC;
					else					  Count = PRESS_MSEC / CHECK_MSEC;
			}
			
		}
}


ISR(TIMER0_OVF_vect)
{

void DebounceSwitch1(unsigned char *Key_changed, unsigned char *Key_pressed);

}

What am I doing wrong?
Could you check this debouncing function.
I took it from the guide for debouncing.

Oh and I am using sei(); for enabling global interrupts I forgot to write

Adam

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

You could look at one of the published debounce routines in Tools. Otherwise, just poll the switch for a fixed period of time and count up the majority vote.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
ISR(TIMER0_OVF_vect) 
{ 

void DebounceSwitch1(unsigned char *Key_changed, unsigned char *Key_pressed); 

} 

Why are you declaring a function inside an ISR? I presume you meant to call the function. But if you do, what are you going to send into the function? Having local variables in the ISR wouldn't make sense since they would disappear once the ISR ended. And if you used global variables, why not just access them from within the function rather than send them in?

Regards,
Steve A.

The Board helps those that help themselves.

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

Exactly Steve I have noticed the same yesterday.
I have changed it for function and it didnt help.
But as you said my main question is that why in this function I need pointers ???

Why authour used them ?
Well actually what for we have to provide them to the function if we change them totally in function ?

Steve said:

Quote:
Having local variables in the ISR wouldn't make sense since they would disappear once the ISR ended.

So why author used them ??

Well guyes I am asking about this cause I am tring to use this algorithm from the guide for debouncing which you recommend but as you can see there are plenty complications.

So now my question is maybe somebody have an example of this function ??

I took mine from:

http://www.ganssle.com/debouncin...