I'm new to MSP430 and microcontrollers. Right now I'm learning interrupt routines and trying to write a program that changes the LED's state (OFF-ON-BLINK) by every press on P1.1 button. I have used the "switch-case" statement to achieve this and to control the switch statement's variable, I used a port interrupt. And for the blinking operation, I used a timer interrupt. Everything works as it should be. The program starts with the LED is off. One press on the button turns the LED on and if it's pressed once more, it starts to blink. And one more press, then the program should go to the initial position and turn the LED off. But there is a problem with the blink case.
When the LED starts to blink, the program stuck at the infinite loop where the timer get involved to toggle the LED state. Because of that, a press on the button has no effect, the LED continues to blink. Instead of this, the program should return back to Case 0 (see the code below)
Without the interrupts, (by usign polling etc.) my code works flawlessly. So in order to not overcrowd here, I won't post my code completely.
volatile unsigned int mode;
#pragma vector = port_vector_here
__interrupt void anotherNameHere (void) {
__delay_cycles(1000);
mode++;
P1IFG &= ~BIT1;
}
#pragma vector = timer_vector_here
__interrupt void someNameHere (void) {
P1OUT ^= BIT0;
TA0CTL &= ~TAIFG;
}
int main(void) {
/* Port settings, P1.0 to output, P1.1 to input etc.
* Port Interrupt settings, IES, IRQ etc.
* Timer settings, TA0CTL, SMCLK clock etc.
* The configured as it should be, there is no problem.*/
mode = 0;
while (1) {
if (mode > 2) {
mode = 0;
}
switch (mode) {
case 0: P1OUT &= ~BIT0;
break;
case 1: P1OUT |= BIT0;
break;
// Case 2 is the problematic part
case 2: TA0CTL = TASSEL_2 + MC_1 + TACLR + TAIE;
TA0CCR0 = 50000;
TA0CTL &= ~TAIFG;
while(1) {}
// Program stucks here (in while loop). When I debug it on CCS, I can see that a press on the button triggers the port interrupt but program returns to this line after completing the ISR. So it can't go out of Case 2.
break;
}
}
}
As I said in the comment part, the program stucks at the while loop that triggers the timer. As far as I know, I have to use an infinite loop to trigger a timer interrupt but I don't know how to skip over that infinite loop after triggering and executing commands in the Timer ISR.
How can I do this? How can I skip the infinite loop over to return to the initial position?
anotherNameHere
really a good name for a button press ISR? \$\endgroup\$while (1) {}
dowhile (mode == 2) {}
instead. \$\endgroup\$delay(n)
, no long or infinite loops. Instead, make the int handler signal for the main loop to do the slow work (which can then be interrupted) \$\endgroup\$