cancel
Showing results for 
Search instead for 
Did you mean: 

Push Button ISR executed many times

hicham
Associate II
Posted on July 01, 2008 at 18:07

Push Button ISR executed many times

6 REPLIES 6
hicham
Associate II
Posted on May 17, 2011 at 09:50

If you believe that the rising edge is the problem, I have also tried with the falling edge but without success.

hicham
Associate II
Posted on May 17, 2011 at 09:50

Hi fellas,

I have been pulling my hair off during the past two weeks trying to track down the reason(s) behind the following problem.

I successfully made the external interrupt 5 work by:

1 - Setting the GPIO3 pin 5 (GPIO3 is enabled in startup file)

GPIO_InitTypeDef GPIO_InitStructure;

GPIO_InitStructure.GPIO_Direction = GPIO_PinInput;

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;

GPIO_InitStructure.GPIO_Type = GPIO_Type_PushPull ;

GPIO_InitStructure.GPIO_IPConnected = GPIO_IPConnected_Disable; //GPIOIN[3] bit 5 set to 0

GPIO_InitStructure.GPIO_Alternate = GPIO_InputAlt1; // does not really matter since pin 5 runs in its default input function

GPIO_Init (GPIO3, &GPIO_InitStructure);

2- SCU set up

// Connect Pin P3.5 to VIC1.11 chanel

SCU->WKUPSEL &= ~0x0005;

SCU->WKUPSEL |= 0x0005;

3- VIC 1 set up

//VIC1.10 is for external interrupts with button 3

VIC1->VAiR[10] = (unsigned int)&Button_IRQ_Handler; /* Setup external interrupt 5 Hndl addr */

VIC1->INTECR &= 0x0400; // First diasble channel 10 for VIC 1 , to avoid spurious interrupts, as recommended in the reference manual

VIC1->VCiR[10] &= 0xFFC0;

VIC1->VCiR[10] |= 0x002A; // enable interupt with vector 10

4- WIU set up

WIU->TR &= 0x00000000;

WIU->TR |= 0x00000040;// Rising edge for external interrupt 5

WIU->PR |= 0xFFFFFFFC; //Clear pendind interupt

WIU->CTRL &= 0x00;

WIU->CTRL |= 0x02; //Global WIU intr enable

WIU->MR &= 0x00000000;

WIU->MR |= 0x00000020; //Accept external interupt 5

VIC1->INTER |= 0x0400; // Then Enable channel 10 for VIC 1

5- for the sake of completeness Button_ISR

short numberofPushes = 0;

__irq void Button_IRQ_Handler (void){

numberofPushes = numberofPushes+1;

HW_LED_ioctl(0x20);// simply toggles the LED 0

WIU->PR |= 0xFFFFFFFC; //Clear pending interupt

VIC1->VAR = 0; // Clear interupt in VIC1

VIC0->VAR = 0; // Clear interupt in VIC0

}

I use Keil µvision V3.53, with Keil MCBSTR9 version 4 (based on STR912FW44)

Everything works fine EXCEPT that the ISR gets sometimes executed 2 or 3 times while the button was pushed only once. I was certain of that after I used a memory watch on the variable numberofPushes. Besides,

The interrupt is acknowledged in the ISR, and in debug mode I can clearly see that there is no pending interrupt in the VICs registers (in simulated peripherals).

Can anyone tell me what's going on here. :-[

jpeacock2
Associate II
Posted on May 17, 2011 at 09:50

If you are using a mechanical pushbutton switch, how do you debounce it? Switches typically cause several make-break connections as they are closed or released. It sounds like your software is working properly.

hicham
Associate II
Posted on May 17, 2011 at 09:50

Thanks for the hint 😉 I am indeed using a mechanical switch.

Any ideas of how to make the ISR REALLY execute once when the button is pushed down?

dbarbarine
Associate II
Posted on May 17, 2011 at 09:50

Hi, correct me if I'm wrong, but after looking at that posted code, I notice that the rising/falling edge bit is actually set for interrupt 6, not 5. Could this be causing some of your issues?

Posted:

4- WIU set up

WIU->TR &= 0x00000000;

WIU->TR |= 0x00000040;// Rising edge for external interrupt 5

Should be:

4- WIU set up

WIU->TR &= 0x00000000;

WIU->TR |= 0x00000020;// Rising edge for external interrupt 5

daniel8
Associate II
Posted on May 17, 2011 at 09:50

You could start a timer once you see the first interrupt. That timer disables the button interrupt, and reads the switch after 50ms, re-enabling that interrupt after its done.