• Join
  • Sign In with my.TI Login
Texas Instruments
  • Products
  • Applications
  • Tools & Software
  • Support & Community
  • Sample & Buy
  • About TI
Sample & Purchase Cart Sample & Purchase Cart
  • Search
  • Advanced
TI E2E™ Community
  • Support Forums
  • Blogs
  • Groups
  • Videos
  • 简体中文
  • More ...
TI Home » TI E2E Community » Support Forums » Microcontrollers » MSP430™ Microcontrollers » MSP430 Ultra-Low Power 16-bit Microcontroller Forum » Button down vs button up, different actions
Share
MSP430™ Microcontrollers
  • Forum
  • Announcements
  • E2E Wiki
Options
  • Subscribe via RSS
MSP430 Resources
  • MSP430 Product Folder
  • MSP-EXP430G2 - MSP430 LaunchPad Value Line Development kit
  • MSP430 Getting Started Guide
  • MSP430 Microcontroller Projects
  • More Resources >
  • Forums

    Button down vs button up, different actions

    This question is not answered
    David Hutchison1
    Posted by David Hutchison1
    on Apr 29 2012 13:45 PM
    Prodigy20 points

    Hi all,

    Noob question here. I have the example code that turns on an LED when a button is pressed. Now I want to do one action when a button is pressed, and do another action when the button is released. I thought I should just look at P1IES to see if I'm currently looking for a rising or a falling edge, and problem solved. However it doesn't appear to be working.

    In the following program I'm trying to toggle one button on when the button is pressed, and the other one on when the button is released. (Of course I could do this by toggling them differently, but I'm trying to understand something more basic here.) However BOTH LEDs turn on when the button is pressed. What am I doing wrong?

    int main(void)
    {
    WDTCTL = WDTPW + WDTHOLD;
    P1DIR |= (LED0 + LED1); // Set P1.0 and P1.6 to output direction. P1.3 must stay at input. It has the button on it.
    P1SEL = 0x0;
    P1OUT &= ~(LED0 + LED1); // set P1.0 and P1.6 to 0 (LED OFF)
    P1IE |= BUTTON; // P1.3 interrupt enabled

    P1IFG &= ~BUTTON; // P1.3 IFG cleared

    __enable_interrupt(); // enable all interrupts
    for(;;)
    {}
    }

    // Port 1 interrupt service routine
    #pragma vector=PORT1_VECTOR
    __interrupt void Port_1(void)
    {
    P1OUT ^= LED0;
    if (P1IES & BIT3 == 0) { // if the interrupt edge this time was from low to high (so, that corresponding bit is a zero), and it has triggered, then we just pulled the button

    P1OUT ^= LED0;
    } else if (P1IES & BIT3 == BIT3) { // if the interrupt edge this time was from high to low (so, that corresponding bit is a one), and it has triggered, then we just released the button
    P1OUT ^= LED1;
    }

    P1IFG &= ~BUTTON; // P1.3 IFG cleared
    P1IES ^= BUTTON; // toggle the interrupt edge. This means that next time this will trigger on the opposite edge to what it triggered on this time

    }

    Report Abuse
    • Reply
    You have posted to a forum that requires a moderator to approve posts before they are publicly available.
    All Replies
    • Chester Gillon
      Posted by Chester Gillon
      on Apr 29 2012 14:32 PM
      Mastermind6315 points

      David Hutchison1
      However BOTH LEDs turn on when the button is pressed.

      Switches tend not to cleanly change state, but "bounce" between open/closed when pressed or released. i.e. when the button is pressed you may detect multiple edges before the switch settles to a steady state. Search this forum for "debounce" for more information.

      Also, the contents of the P1IES register is undefined after a device register, so it should be initialized before the P1IFG &= ~BUTTON line.

      Report Abuse
      • Reply
      You have posted to a forum that requires a moderator to approve posts before they are publicly available.
    • David Hutchison1
      Posted by David Hutchison1
      on Apr 29 2012 15:13 PM
      Prodigy20 points

      Thanks,

      Yep I'm familiar with debounce, but was trying to strip extraneous stuff away to get at the heart of the problem. Even with bouncing I believe this should work, as it's just toggling LED0 whenever it goes from low to high (and doing nothing to LED1), and toggling LED1 whenever it goes from high to low (and doing nothing to LED0). Even with bouncing

      I also added P1IES = 0x0; as you recommend. Thanks for that.

      However I guess I'm still unsure why the following lines in the interrupt code don't produce the desired results:

      if (P1IES & BIT3 == 0) { // if the interrupt edge this time was from low to high (so, that corresponding bit is a zero), and it has triggered, then we just pushed the button
          P1OUT ^= LED0;
      } else if (P1IES & BIT3 == BIT3) { // if the interrupt edge this time was from high to low (so, that corresponding bit is a one), and it has triggered, then we just released the button
          P1OUT ^= LED1;
      }

      Desired result is that on a rising edge, LED0 should toggle, and on a falling edge, LED1 should toggle.

      [note that I had an extra P1OUT ^= LED0 in the original code -- this was incorrect but was not the source of the problem]

      Thanks for lookin'!

      Report Abuse
      • Reply
      You have posted to a forum that requires a moderator to approve posts before they are publicly available.
    • Chester Gillon
      Posted by Chester Gillon
      on Apr 29 2012 16:16 PM
      Mastermind6315 points

       Based upon the I/O pins in use I assume a MSP430 LaunchPad (MSP-EXP430G2) is used. On the LaunchPad pressing the S2 button takes P1.3 low. i.e. a high to low transition means a button press and a low to high transition means a button release. This is the opposite polarity to that expected by the code.

       The reason I mentioned the debounce is that a rapid series of edges caused by switch bounce could trigger multiple interrupts which may lead to both leds being turned on.

      Report Abuse
      • Reply
      You have posted to a forum that requires a moderator to approve posts before they are publicly available.
    • TonyKao
      Posted by TonyKao
      on Apr 29 2012 21:00 PM
      Genius3770 points

      Hi David,

      In the x2xx family user guide, it states that "Writing to P1IES, or P2IES can result in setting the corresponding interrupt flags."

      This may explain what your seeing, since the interrupt flag may be triggered twice for the same edge by setting P1ES during your interrupt.

      For your purposes, I would suggest using a Timer_A capture on the input pin, which would also have the side-effect of helping with debouncing.

      Tony

      Report Abuse
      • Reply
      You have posted to a forum that requires a moderator to approve posts before they are publicly available.
    • Chester Gillon
      Posted by Chester Gillon
      on Apr 30 2012 17:16 PM
      Mastermind6315 points

      TonyKao
      In the x2xx family user guide, it states that "Writing to P1IES, or P2IES can result in setting the corresponding interrupt flags."

      The section from the user guide is:

      TonyKao
      This may explain what your seeing, since the interrupt flag may be triggered twice for the same edge by setting P1ES during your interrupt.

      Doesn't the following sequence mean its OK to change PxIESx within the ISR:

      a) PxIESx is initialized to 0, so PxIFGx flag is set with a low-to-high transition.

      b) A low-to-high transition occurs on the input which triggers one interrupt by setting PxIFGx.

      c) While the input remains high PxIESx is changed from 0 to 1, selecting a high-to-low transition, which leaves PxIFGx unchanged.

      d) A high-to-low transition occurs on the input which triggers one interrupt by setting PxIFGx.

      e) While the input remains low PxIESx is changed from 1 to 0, selecting a low-to-high transition, which leaves PxIFGx unchanged.

      f) The sequence repeats from b) 

      Report Abuse
      • Reply
      You have posted to a forum that requires a moderator to approve posts before they are publicly available.
    • TonyKao
      Posted by TonyKao
      on May 01 2012 16:00 PM
      Genius3770 points

      Hi Chester,

      Yes you're right, that shouldn't affect PxIFGx in this case.

      On further review of the code, I think I know why both LEDs are permanently set.

      LED0,1 are initialized to 0.

      When the button is first pressed, LED0 is toggled twice since it is from low-to-high. Hence LED0 = 0, LED1 =0.

      When the button is released, LED0 is toggled once, and LED1 is toggled once since it is high-to-low. Hence LED0 = 1, LED1 = 1.

      Tony

      Report Abuse
      • Reply
      You have posted to a forum that requires a moderator to approve posts before they are publicly available.
    TI E2E™ Community
    • Support Forums
    • Blogs
    • Videos
    • Groups
    • Site Support & Feedback
    • Settings
    TI E2E™ Community Groups
    • TI University Program
    • Make the Switch
    • Microcontroller Projects
    • Motor Drive & Control
    Other Communities
    • Deyisupport
    • Designsomething.org
    • beagleboard.org
    • TI on Element 14
    • TI on TechXchangeSM
    Other Technical & Support Resources
    • WEBENCH® Design Center
    • Product Information Centers
    • Technical Documents
    • TI Design Network
    • TI Technical Articles
    • TI Training

    All content and materials on this site are provided "as is". TI and its respective suppliers and providers of content make no representations about the suitability of these materials for any purpose and disclaim all warranties and conditions with regard to these materials, including but not limited to all implied warranties and conditions of merchantability, fitness for a particular purpose, title and non-infringement of any third party intellectual property right. TI and its respective suppliers and providers of content make no representations about the suitability of these materials for any purpose and disclaim all warranties and conditions with respect to these materials. No license, either express or implied, by estoppel or otherwise, is granted by TI. Use of the information on this site may require a license from a third party, or a license from TI.

    Content on this site may contain or be subject to specific guidelines or limitations on use. All postings and use of the content on this site are subject to the Terms of Use of the site; third parties using this content agree to abide by any limitations or guidelines and to comply with the Terms of Use of this site. TI, its suppliers and providers of content reserve the right to make corrections, deletions, modifications, enhancements, improvements and other changes to the content and materials, its products, programs and services at any time or to move or discontinue any content, products, programs, or services without notice.

    Follow Us Texas Instruments on Facebook Texas Instruments on Twitter Texas Instruments on LinkedIn Texas Instruments on Google+
    TI Worldwide | Contact Us | my.TI Login | Site Map | Corporate Citizenship | mobile m.ti.com (Mobile Version)

    TI is a global semiconductor design and manufacturing company. Innovate with 100,000+ analog ICs and
    embedded processors, along with software, tools and the industry’s largest sales/support staff.

    © Copyright 1995-2013 Texas Instruments Incorporated. All rights reserved.
    Trademarks | Privacy Policy | Terms of Use