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.
I am trying to write a basic interrupt code using interrupts from Button S2 (Port 1.1) to toggle LED1 (Port P1.0).
I have gotten polling to register button presses but my interrupt code does not appear to be working. Specifically, using the debugger, it appears the code is not passing the __bis_SR_register(GIE) statement.
Does anyone know why this code is not working to use interrupts to toggle an LED?
My code is:
#include <msp430f5529.h> #define RED_LED BIT0 #define BUTTON BIT1 int main() { P1DIR |= RED_LED; P1OUT &= ~RED_LED; // Set as input pin P1DIR &= ~BUTTON; // Set pullup resistor P1REN |= BUTTON; P1OUT |= BUTTON; // Interrupt Edge Select P1IES &= ~BUTTON; // Clear Interrupt Flag P1IFG &= ~BUTTON; // Set as interrupt pin P1IE |= BUTTON; __bis_SR_register(GIE); while(1) { } } #pragma vector=PORT1_VECTOR __interrupt void port1_isr(void) { P1OUT ^= RED_LED; P1IFG &= ~BUTTON; }
Thank you for the quick response.
Putting a "__nop()" call in the while loop did fix the debugger appearing to never pass the __bis_SR_register(GIE) call. It now properly steps through the while loop.
However, the interrupt still seems to not be called. I simplified my code slightly so that the LED starts in the low position, and if the interrupt is ever called, it will turn to high. (I think this should elimate the possibility that the ISR is called but because of switch bounce I don't realize).
Still, the LED never switches to on which seems to mean the ISR is never called.
My code is now:
#include <msp430.h> #define RED_LED BIT0 #define BUTTON BIT1 int main() { P1DIR |= RED_LED; P1OUT &= ~RED_LED; // Set as input pin P1DIR &= ~BUTTON; // Set pullup resistor P1REN |= BUTTON; P1OUT |= BUTTON; // Interrupt Edge Select P1IES &= ~BUTTON; // Clear Interrupt Flag P1IFG &= ~BUTTON; // Set as interrupt pin P1IE |= BUTTON; //__bis_SR_register(GIE); __enable_interrupt(); while(1) { __nop(); } } #pragma vector=PORT1_VECTOR __interrupt void port1_isr(void) { P1OUT |= RED_LED; P1IFG &= ~BUTTON; }
Hi,
I placed this code as the first line of the main function, but it seems that disabling the watchdog is unfortunately not changing anything either.
Hm. I added that line, and pushing the P1.1 button turned on the LED (Rev 1.5 Launchpad).
1) Have you tried setting a breakpoint in the ISR?
2) Is the jumper next to the LED installed?
3) One curiosity: I had to explicitly add:
#define __nop() do {asm volatile(" nop");}while(0)
to get it to build. (intrinsics.h has _nop(), with one underbar.) Apparently you were getting it from elsewhere(?). Maybe try adding that line or change the function name to _nop().
[Edit: Added a blank to the nop instruction; results are unchanged.]
Hi,
Thank you for all the help.
I have found the problem with my code.
It seems to define the interrupt I needed to be using __attribute ((interrupt(PORT1_VECTOR))) instead of #pragma vector=PORT1_VECTOR __interrupt
My final code that works is (note: this does not include button debouncing):
#include <msp430f5529.h> #define RED_LED BIT0 #define BUTTON BIT1 int main() { WDTCTL = WDTPW + WDTHOLD; // Set LED1, P1.0, as output P1DIR |= RED_LED; // Set LED1, P1.1, to low P1OUT &= ~RED_LED; // Set as input pin P1DIR &= ~BUTTON; // Set pullup resistor P1REN |= BUTTON; P1OUT |= BUTTON; // Interrupt Edge Select P1IES &= ~BUTTON; // Clear Interrupt Flag P1IFG &= ~BUTTON; // Set as interrupt pin P1IE |= BUTTON; // Enter Low Power Mode 0 and enable maskable interrupts __bis_SR_register(LPM0_bits + GIE); } void __attribute__ ((interrupt(PORT1_VECTOR))) port1_isr(void) { // Switch LED1 P1OUT ^= RED_LED; // Clear port 1 interrupt flag P1IFG &= ~BUTTON; }
**Attention** This is a public forum