Skip to main content
Visitor II
July 1, 2008
Question

Push Button ISR executed many times

  • July 1, 2008
  • 6 replies
  • 1508 views
Posted on July 01, 2008 at 18:07

Push Button ISR executed many times

    This topic has been closed for replies.

    6 replies

    hichamAuthor
    Visitor II
    May 17, 2011
    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.

    hichamAuthor
    Visitor II
    May 17, 2011
    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. :-[

    Visitor II
    May 17, 2011
    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.

    hichamAuthor
    Visitor II
    May 17, 2011
    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?

    Visitor II
    May 17, 2011
    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

    Visitor II
    May 17, 2011
    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.