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.

MSP430FR6989: Why does the onboard button interrupt not work in this code?

Part Number: MSP430FR6989

In the code below, I wish to use one of the onboard switches to toggle the direction and output of P2.0. Commented out sections are things I've tried

The issue is that when I press the onboard switch, an LED I'm driving with P2.0 will turn off, but only so long as I press the switch. This is not consistent with the desire to toggle the switch. In debug mode, the ISR does not seem to get called at all.

I can only assume I've configured something incorrectly, but I'm unsure what I haven't done. In a different program, pressing switch 1 using initialization code properly resets a matrix. That code I've included below as well.

#include <msp430.h> 


//MAIN
int main(void)
{
	WDTCTL = WDTPW | WDTHOLD;	// stop watchdog timer
	PM5CTL0 &= ~LOCKLPM5;	//unlock power management

	P1DIR &= ~BIT1;
	P1REN |= BIT1;
	P1OUT |= BIT1;
	P1IES |= BIT1;
	P1IFG &= ~BIT1;
	P1IE |= BIT1;

	P2DIR |= BIT0;
P2OUT |= BIT0; __enable_interrupt(); while(1) { __low_power_mode_3(); } return 0; } /*Button Interrupt*/ #pragma vector=PORT1_VECTOR __interrupt void Port_1(void) { if(P1IFG & BIT1){ P2DIR ^= BIT0;
P2OUT ^= BIT0; } P1IFG &= ~BIT1; __low_power_mode_off_on_exit(); /* switch(__even_in_range(P1IV,P1IV_P1IFG7)) { case P1IV_NONE: break; // Vector 0: no interrupt case P1IV_P1IFG0: break; // Vector 2: P2.0 case P1IV_P1IFG1://BIT P1IE &= ~BIT1;//disable interrupts P1IFG &= ~BIT1;//clear flags P2DIR ^= BIT0;//toggle
P2OUT ^= BIT0; break; case P1IV_P1IFG2: break; case P1IV_P1IFG3: break; case P1IV_P1IFG4: break; case P1IV_P1IFG5: break; // Vector 12: P2.5 case P1IV_P1IFG6: break; // Vector 14: P2.6 case P1IV_P1IFG7: break; // Vector 16: P2.7 default: break; }*/ /*if(P1IFG & BIT1)//If button 1 caused interrupt { P2DIR ^= BIT0;
P2OUT ^= BIT0; P1IFG &= ~BIT1; //__low_power_mode_off_on_exit();//re-enable this after selecting low power mode? }*/ //END INTERRUPT BRACKET }
And the second bit of code:


#include <msp430.h>
#define BUTTON1 BIT1

//Globals
unsigned int matrix[5] = {0,0,0,0,0};


//===============MAIN================
int main(void) {
    //volatile unsigned int i;

	WDTCTL  = WDTPW | WDTHOLD;	 // Stop watchdog timer

    P1DIR   &= ~BUTTON1;        // input
    P1OUT   |= BUTTON1;          // give pullup/down resistor a '1' so it pulls up
    P1REN   |= BUTTON1;          // enable pullup/down

    PM5CTL0 &= ~LOCKLPM5;        // Unlock ports from power manager, causes interrupts!

    P1IES   |= BUTTON1;          // Interrupt on falling edge
    P1IFG   &= ~BUTTON1;         // clear interrupt flag
    P1IE    |= BUTTON1;          // enable interrupt

    __enable_interrupt();

    while(1)                      // continuous loop
    {

        __low_power_mode_3();     // going to sleep but keep ACLK running
    }

	return 0;
}







//=======================INTERRUPTS============================
// Interrupt Service Routine for Port 1
#pragma vector=PORT1_VECTOR       // associate funct. w/ interrupt vector
__interrupt void Port_1(void)     // name of ISR
{
	if(P1IFG & BUTTON1){             // button 1 caused interrupt
		//count = 0;
		matrix[0] = 0;
		matrix[1] = 0;
		matrix[2] = 0;
		matrix[3] = 0;
		matrix[4] = 0;
		P1IFG &= ~BUTTON1;           // clear interrupt flag of P1 BUTTON1
        __low_power_mode_off_on_exit();
	}
}

  • Oh, to add: the matrix should be initialized differently. I copied that over incorrectly. It should be something like this:

        unsigned int matrix[5] = {5,5,5,5,5};

  • That switch is almost certain to trigger more than one interrupt both on closure and release. This is contact bounce. Which means that you will XOR the pin direction many times.

    Some button debounce is in order. A small capacitor (10nF or so) to ground on the input pin would do it or there are of course software approaches.

  • I can verify that debounce is not the issue. I tried both a simple debounce loop, and something even simpler:

        P2DIR = 0x00;//replace the toggle in the ISR with this.

    That way, even if the toggle was causing the issue in the older version of the code, this assignment statement can't be toggled, and multiple calls to the ISR result in the same assignment. So I'm still stuck with the onboard switch not behaving as expected, and I'm guessing that the issue is in how I set it up.

  • Okay, I've resolved the issue.

    As it turns out, the code was fine as written (putting aside the lack of debounce). When I ran the program in debug mode, it was simply not stepping into the ISR. I tried reflashing the program, and this did not work. Then I switched to my laptop, copied the project over to it, and flashed it again, and it now works.

    I had a similar issue when CCS tried to update the controller a few months ago, when I first started to use it. I'm not sure what caused this - and I haven't been able to reproduce it since moving back to my desktop (flashing the program now works fine).

**Attention** This is a public forum