How to code multiple PORT2 interrupts?

Hello everyone,

I am trying to make a portable blood pressure monitor with MSP430F2274. In addition to measuring blood pressure, the device is supposed to store the blood pressures along with the time the measurement is taken.

On port 2, i have four buttons interfaced on p2.0 to p2.3. all the buttons generate interrupts to wake up the CPU from LPM3.

I have the following problem in running the test code:

on pressing any of the four buttons, the code is entering the PORT2_ISR, but the code is not detecting which button is pressed. I have used a simple switch case statement on P2IFG, but when I tried to debug, i found that P2IFG reset after entering the ISR.

What can be done to detect which of the four buttons is pressed?

I am using IAR embedded workbench platform and am programming in C language.

Your suggestions will be really helpful.

  • I suspect that the debugger resets P2IFG.

    How does you test code look like?

  • In reply to old_cow_yellow:

    Yes, the Simulator resets P2IFG.

    I have posted the PORT2_ISR for convenience..

     

    #pragma vector=PORT2_VECTOR

    __interrupt void Port2_interrupt(void)  

    {

      switch(P2IFG)

      {

      case 0x08:                                // SET button interrupt

      set_time();

      P2IFG &= ~0x01;

      case 0x01:

      case 0x02:

      case 0x04: break;

      }

    }

    this code is supposed to check for which button is pressed on PORT2.
    but none of the cases are getting executed, because P2IFG resets to 0x00 on entry in interrupt.

  • In reply to Jimit Raja:

    This code won't work.

    If two interrupts are pending, P2IFG will be 0x03 or 0x0a or whatever combination of events is pending.

    You cannot use a bitfield in a switch statement.

    if your MSP has a P2IV register (5x/6x family only), use it. It always returns the nubmer of the highest pending interrupt, and at the same time resets its IFG bit.
    So you can loop through it with a switch and if it reads 0, no more interrupts are pending.
    It also eliminates a nasty baug in which a por tinterupt is lost if it happens the very moment you're reading the IFG register, or that you may clear it yourself by a read-modify-write instruction while you are clearing a different IFG bit.

     

  • In reply to Jens-Michael Gross:

    Mr. Jens-Michael,

    the mistake in the code is rectified by putting a 'default' statement. hence the code will do nothing if there are two interrupts. Thankyou for showing me the error.

    It is really unlikely that two interrupts will occur, because the interrupts are generated by pushbuttons. even if they occur if some guy is trying to be nasty with the machine, doing nothing seems to be a satisfactory solution.

    As I've already told, i am using a 2x series MSP430, and hence do not have a PAIV register.

    What should I do here?

  • In reply to Jimit Raja:

    Jimit Raja
    As I've already told, i am using a 2x series MSP430, and hence do not have a PAIV register.

    When answering to a post, you don't see the whole thread anymore, and I was a bit in a hurry too, so I didn't check.

    One thing that's, well not 'wrong' but also not entirely right, is , that you ignore the bouncing of the pushbuttons. Manual pushbuttons are nbot ideal. You'll get multiple interrupts for several milliseconds.

    The usual way to do debouncing is to use a timer delay before acting. If a port interrupt is triggered, the 'offending' port interrupt is disabled, and a timer is started. When the timer expires, it looks for the current value of the port bit (with the now settled signal) and determines whether it is a pushed button or not. Then it re-enables the port interrupt.

    Jimit Raja
    even if they occur if some guy is trying to be nasty with the machine, doing nothing seems to be a satisfactory solution.

    I agree. For this scenario, it is a valid and working solution.

  • In reply to Jimit Raja:

    #pragma vector=PORT2_VECTOR
    __interrupt void Port2_interrupt(void) 
    {
      switch(P2IFG)
      {
        case 0x08:     
          set_time();
          Break;
        case 0x01:
          ...
          Break;
        case 0x02:
          ...
          Break;
        case 0x04:
          ...
          break;
      }
      P2IFG = 0;
    }

  • In reply to old_cow_yellow:

    Mr. old_cow_yellow,

    My question is that as soon as i enter the subroutine, P2IFG already becomes zero. i am working with the simulator. and i am not able to detect any button presses because of this.

    thanks for giving the code in a better form, but if P2IFG becomes zero before switch statement occurs, any code that uses P2IFG as a switch variable wont work.

  • In reply to Jens-Michael Gross:

    Mr. Jens-Michael,

    Jens-Michael Gross

    When answering to a post, you don't see the whole thread anymore, and I was a bit in a hurry too, so I didn't check.

    Never mind sir, I understand.

    Jens-Michael Gross

    The usual way to do debouncing is to use a timer delay before acting. If a port interrupt is triggered, the 'offending' port interrupt is disabled, and a timer is started. When the timer expires, it looks for the current value of the port bit (with the now settled signal) and determines whether it is a pushed button or not. Then it re-enables the port interrupt.

    Thank you for the suggestion. will surely apply. can you tell me how much delay is required?

    My main question is still a question sir, what can be done in a 2x series MSP430 to detect which port interrupt is generated? P2IFG is not working in my case.

     

     

  • In reply to Jimit Raja:

    Jimit Raja
    .... i am working with the simulator. and i am not able to detect any button presses because of this....

    Do not use simulator. Use the real hardware.

  • In reply to old_cow_yellow:

    old_cow_yellow

    Jimit Raja
    .... i am working with the simulator. and i am not able to detect any button presses because of this....

    Do not use simulator. Use the real hardware.

    Are you sure this will do the trick?

    As far as I know, simulator has always done what real hardware has done actually.. Hence i do not try real hardware until i get satisfactory results on the simulator...

    but in this case, are you sure it is a simulator bug and will be resolved in hardware??