Question

I was programming for external interrupt using ATmega128. I set external interrupt 0 and 1 to falling edge triggered interrupt. The interrupt has to count the number of times the switch is pressed. But when the key is pressed once, the interrupt is called 2 or 3 times and so it counts higher. What is the problem here ?

My interrupt code is here

ISR(INT1_vect){
    cli();  
    ++push_cntr1;printf("p1:%d,",push_cntr1);
    sei();  
}
ISR(INT0_vect){
    cli();
    ++push_cntr0;printf("p0:%d,",push_cntr0);
    sei();  
}
void interrupt_init(void)       //enable interrupt 0 and 1.
{   
    EICRA |= (1<<ISC01)|(0<<ISC00)|(1<<ISC11)|(0<<ISC10);
    EIFR = 0xFF;
    EIMSK |= (1<<INT1)|(1<<INT0);
    DDRD = 0x00;
}

int main(void)        //main program
{
    dev_init();
    while(1){
        process();
    }
    return 0;
} 
Was it helpful?

Solution

You don't need to clear and set the i bit within the interrupt handlers. It will be taken care of by the compiler.

As for the multiple hits, you could be suffering from "switch bounce." There are many references to this on the web, but the gist is that the voltage in the switch circuit doesn't simply go from 0 to max in a clean jump. This is most often caused by the actual physical bouncing of the electrical contacts.

There are many techniques available to "debounce" a switch. You could try something as simple as recording the tcnt and ignoring interrupts too soon after a previous one.

OTHER TIPS

I can think of two problems you may be having. As was previously mentioned, you may want to try 'debouncing' your input signal.

You may also want to check if your external input is floating; that is to say, does your input have a pullup or pulldown resistor attached, allowing the signal to be pulled high or low respectively when no signal is present? If it doesn't, your input is floating.

Adding a pullup or pulldown resistor eliminates most chances of having random noise affect your signal. Debouncing removes error caused by the actual input itself triggering your microcontroller multiple times.

Here is an example of Debouncing:

Let's use a simple momentary switch as an example. When the switch is first closed, the signal won't go cleanly from OFF to ON. There will be a very, very short period of time where the signal is stabilizing.

** refer to this very interesting image from an oscilloscope, showing approximately how a mechanical switch behaves when it is first closed:

https://a.pololu-files.com/picture/0J790.600.jpg?c2e19ae7a5387b0870b4dbacf5cb7055

If you think about how a microcontroller interprets this signal, it sees multiple spikes before everything is stable. These spikes are totally unpredictable, and so we need to come up with a work-around.

Solution: Debouncing.

There are plenty of sophisticated algorithms used to debounce hardware, but there is a simple procedure you can follow to create your own debounce function.

  1. Interrupt detected, input value recorded
  2. Wait (try 10-20us for starters)
  3. Check the input again.
  4. Is the previously recorded input value the same as the current input value? If so, the signal has stabilized: Register a successful read. If the signal is different, you have detected noise. Wait for the next interrupt, register nothing.

This is a very basic debounce, but the methodology doesn't change that much as they become more advanced.

I hope this helps answer your question.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top