This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

CCS/MSP430FR5994: Interrupt for On-Board Buttons (Switches)

Part Number: MSP430FR5994
Other Parts Discussed in Thread: MSP-EXP430FR5994

Tool/software: Code Composer Studio

I am trying to use interrupts for the two switches (S1 and S2, or P5.6 and P5.5) on the MSP-EXP430FR5994 development kit.  As soon as the interrupts are enabled the ISR starts even though neither of the switches has been pressed.  The value of the interrupt flag is zero (no interrupts set) before the interrupts are enabled but the value is 255 (all interrupts set) immediately inside the ISR until I reset flags 5 and 6 (then the flag is 159, i.e., bits 5 and 6 turned off).  Once a switch is pressed nothing seems to happen. 

Why is the interrupt flag equal to 255 as soon as the interrupts are enabled?  I assume this is why the ISR is activated immediately without waiting for a switch to be pressed.

I imagine the solution is rather trivial but I'm stumped.  Any help would be appreciated.

#include <msp430.h>
#include "driverlib.h"
#include "gpio.h"
#include "stdio.h"
#include "string.h"

int main(void)
{

    WDTCTL = WDTPW | WDTHOLD;      // Stop watchdog timer

//    Configure LEDs and switches

    P1DIR |= BIT0;           // Set P1.0 to output
    P1DIR |= BIT1;           // Set P1.1 to output
    P1OUT &= ~BIT0;          // set P1.0 to Off (red LED)
    P1OUT &= ~BIT1;          // set P1.1 to Off (green LED)

    P5IE |= BIT5;            // P5.5 interrupt enabled (S2)
    P5IE |= BIT6;            // P5.6 interrupt enabled (S1)
    P5IFG &= ~BIT5;          // P5.5 interrupt flag cleared (S2)
    P5IFG &= ~BIT6;          // P5.6 interrupt flag cleared (S1)

    __bis_SR_register(GIE);  // Enable all interrupts

// Disable the GPIO power-on default high-impedance mode to activate previously configured port settings

    PM5CTL0 &= ~LOCKLPM5;

    while(1) {;}
}

#pragma vector=PORT5_VECTOR
__interrupt void Port_5(void)
{

// For now, just toggle each LED, eventually be more specific w.r.t. the switch pressed. P1OUT ^= BIT0; // Toggle P1.0 P1OUT ^= BIT1; // Toggle P1.1 P5IFG &= ~BIT5; // P5.5 interrupt flag cleared P5IFG &= ~BIT6; // P5.6 interrupt flag cleared }

  • SLAU367O Sec. 12.3.1 recommends a different initialization order:
    > 1. Initialize Ports: PxDIR, PxREN, PxOUT, and PxIES
    > 2. Clear LOCKLPM5
    > 3. If not wake-up from LPMx.5: clear all PxIFGs to avoid erroneous port interrupts
    > 4. Enable port interrupts in PxIE
    Only then (presumably) should you set GIE.
    -------------
    In the Launchpad schematics (SLAU678A Fig 26ff) I don't see any external pullups for the buttons. I recommend setting the internal pullups using P5OUT/P5REN.
  • Thanks Bruce.  It works now.  I thought some of the settings you mentioned were already the defaults so I initially skipped them (and they were not included in sample code I found on various websites). And the order in SLAU367O is different from what I had seen on websites with sample code.  My updated code is shown below.  I think I might need to de-bounce the switches since sometimes the LED will blink on then back off (or off then back on) when it should only go off or on depending on its initial state.

    One thing I had to do was initially set all of the interrupt flags for port 5 (not just pins 5 and 6) to zero because if not the ISR would be triggered by another pin on port 5 even without pressing one of the switches.  This was verified by printing the port 5 interrupt flag as the first step in the ISR and seeing that a few of the bits, except 5 and 6, were set.

    /*
    Toggle the red or green LED depending on which on-board button (switch) is pressed.
    The MSP430FR5994 has LEDs on P1.0/P1.1 (red/green) and switches on pins P5.6/P5.5 (S1/S2).
    */
    
    #include <msp430.h>
    #include "driverlib.h"
    #include "gpio.h"
    #include "stdio.h"
    #include "string.h"
    
    
    int main(void)
    {
    
        WDT_A_hold(WDT_A_BASE);        // Stop watchdog timer
    
        GPIO_setAsOutputPin(GPIO_PORT_P1, GPIO_PIN0);         // Set Red LED output
        GPIO_setOutputLowOnPin(GPIO_PORT_P1, GPIO_PIN0);      // Red LED off
        GPIO_setAsOutputPin(GPIO_PORT_P1, GPIO_PIN1);         // Set Green LED output
        GPIO_setOutputLowOnPin(GPIO_PORT_P1, GPIO_PIN1);      // Green LED off
    
        GPIO_setAsInputPinWithPullUpResistor(GPIO_PORT_P5, GPIO_PIN6);                      // S1 P5.6: PxDIR, PxOUT and PxREN registers
        GPIO_selectInterruptEdge(GPIO_PORT_P5, GPIO_PIN6,GPIO_HIGH_TO_LOW_TRANSITION);      // S1 P5.6: PxIES register
    
        GPIO_setAsInputPinWithPullUpResistor(GPIO_PORT_P5, GPIO_PIN5);                      // S2 P5.5: PxDIR, PxOUT and PxREN registers
        GPIO_selectInterruptEdge(GPIO_PORT_P5, GPIO_PIN5,GPIO_HIGH_TO_LOW_TRANSITION);      // S2 P5.5: PxIES register
    
    // Disable the GPIO power-on default high-impedance mode to activate previously configured port settings
    
        PMM_unlockLPM5();
    
    // Set all P5IFG to zero
    
        P5IFG = 0x00;
    
        GPIO_enableInterrupt(GPIO_PORT_P5, GPIO_PIN6);                                      // S1 P5.6: PxIE register
        GPIO_enableInterrupt(GPIO_PORT_P5, GPIO_PIN5);                                      // S2 P5.5: PxIE register
    
        __bis_SR_register(GIE);  // Enable all interrupts
    
        while(1) {;}
    }
    
    #pragma vector=PORT5_VECTOR
    __interrupt void Port_5(void)
    {
    
        switch (P5IFG)
        {
            case 0b01000000: // S1 P5.6 = 64: toggle red LED
            {
                P1OUT ^= BIT0;          // Toggle P1.0
                P5IFG &= ~BIT6;         // P5.6 clear interrupt flag
            }
            break;
            case 0b00100000: // S2 P5.5 = 32: toggle green LED
            {
                P1OUT ^= BIT1;          // Toggle P1.1
                P5IFG &= ~BIT5;         // P5.5 clear interrupt flag
            }
            break;
            default: // should not be here!
            {
              printf("Put an error message here. \n");
            }
            break;
        }
    
    }
    
    

**Attention** This is a public forum