3
\$\begingroup\$

I just got an MSP430F5529 Launchpad and have done one tutorial where i make the LED located at P1.0 blink. I am using code composer studio as my IDE

Now i am trying to get the LED at P1.0 (red) and the one at P4.7 (green) to alternate depending on if the button located at P2.1 is pressed down.

No matter what I do the button doesn't seem to change anything. What's even more odd is that pressing the button changes multiple bits on P2IN instead of just P2.1.

I have tried using the button at P1.1 (actually i tried that first), and i got similar behavior where the button changes multiple bits and sometimes changes none at all. But the worst part is that even if the bits change and it compares the bit of input to what it should be for pressed, it never registers as pressed.

Also i cannot see my variables so i added a 'blah' variable and tried to set it to 0x00 to force myself into the loop, but it doesnt do anything!!!! It's like it just deletes the blah variable.

Here is the code i am trying to get working:

#include <msp430f5529.h>

//defines
#define red_LED   BIT0 //red LED @ P1.0
#define grn_LED   BIT7 //green LED @ P4.7
#define BTN       BIT1 //button is located a P2.1
#define BTN_PRESSED      0x00

//prototypes
void delay(int n);

//main
void main(void) {
    WDTCTL = WDTPW + WDTHOLD; //disable watchdog timer

    unsigned int flash; //variable to store LED flash flag

    P1OUT = 0; //set output as low
    P1DIR |= red_LED;  // set LED pins to outputs

    P4OUT = 0; //set output low
    P4DIR |= grn_LED; //set green LED as output

    /* Setting up Switch */
    P2OUT = 0;                                   //set output as low
    P2DIR &= ~BTN;                               // Set the switch pin to input
    P2REN |= BTN;                                // Use an internal resistor
    P2OUT |= BTN;                                // The internal resistor is pullup

    for (;;) {//inf loop

        for (flash=0; flash<7; flash++) {
            P1OUT |= red_LED;    // red LED on
            delay(60000);             // call delay function
            P1OUT &= ~red_LED;   // red LED off
            delay(60000);             // delay again
        }

        while ((P2IN & BTN) == BTN);  // wait for button press, loop forever while P1IN is high (button unpressed)

        for (flash=0; flash<7; flash++) {
            P4OUT |= grn_LED;    // green LED on
            delay(60000);            // call delay function
            P4OUT &= ~grn_LED;   // green LED off
            delay(60000);            // delay again
        }

        while ((P1IN & BTN) == BTN);  // wait for button press, loop forever while P1IN is high (button unpressed)

    }//end inf loop
} // main


//functions
void delay(int n) {
    //delays for a count of 60000 ticks
    unsigned int count;
    for (count=0; count<n; count++);
} // delay

and here is the test code i am trying to debug to no avail (the button works if i get into the delay() loop, but i can never get into it!

#include <msp430f5529.h>

//defines
#define red_LED   BIT0
#define grn_LED   BIT7
#define BTN       BIT1
#define BTN_PRESSED      0x00

//prototypes
void delay(int n);

//main
void main(void) {
    WDTCTL = WDTPW + WDTHOLD; //disable watchdog timer

    unsigned int flash; //variable to store LED flash flag

    P1OUT = 0; //set output as low
    P1DIR |= red_LED;  // set LED pins to outputs

    P4OUT = 0; //set output low
    P4DIR |= grn_LED; //set green LED as output

    /* Setting up Switch */
    P2OUT = 0;                                   //set output as low
    P2DIR &= ~BTN;                               // Set the switch pin to input
    P2REN |= BTN;                                // Use an internal resistor
    P2OUT |= BTN;                                // The internal resistor is pullup

    int blah = 0;

    for(;;){
        if((blah) == BTN_PRESSED){
            delay(5);             // call delay function
        }
    }

//functions
void delay(int n) {
    //delays for a count of 60000 ticks
    unsigned int count;
    for (count=0; count<n; count++);
} // delay

I must be doing something fundamentally wrong because blah never appears in my debuggers variable list and the delay(5) never runs!

\$\endgroup\$
9
  • \$\begingroup\$ So what part of your code does work? Anything? May I suggest taking a step back and just get one of the LEDs to blink without using a button, just in a loop with a delay between on and off? Once that works then move on. This will verify that you have the IDE and part setup correctly. \$\endgroup\$ Commented Aug 5, 2015 at 23:16
  • \$\begingroup\$ i did that, i can eve get the two LEDs to alternate, but the second i try to use a button to control turning one on it doesn't seem to work. I can't seem to get into the if statement that checks when the button is pressed. \$\endgroup\$ Commented Aug 5, 2015 at 23:21
  • \$\begingroup\$ Okay, so up to this statement (in your first bit of code) while ((P2IN & BTN) == BTN); works? That is you see the red LED flash? \$\endgroup\$ Commented Aug 5, 2015 at 23:25
  • \$\begingroup\$ Make sure optimizations are turned off in the compiler settings. The optimizer may have optimized your code such that the debugger shows unexpected behavior. \$\endgroup\$
    – kkrambo
    Commented Aug 5, 2015 at 23:26
  • \$\begingroup\$ You may not get the behavior you want without using an interrupt on the button. Try holding down the button for at least a second and see if your green LED starts flashing. I suspect the MSP430 isn't seeing the button press. \$\endgroup\$ Commented Aug 5, 2015 at 23:34

1 Answer 1

3
\$\begingroup\$

The compiler sees that the delay() loop is empty, so it cleverly concludes that the function can compute the same result much faster by omitting the loop altogether.

The blah variable has the same problem: the compiler sees that its value never gets changed inside the program, so it is effectively a constant, and does not need to be actually stored anywhere. (And the if((blah) == BTN_PRESSED) can never happen, so it can be omitted.)

To tell the compiler that it should actually access some variable, you have to declare that variable as volatile:

volatile int blah = 0;        // allows changes with the debugger
...
volatile unsigned int count;  // force the compiler to actually count up, even
                              // if the compiler does not see any effect

Please note that all registers like P2IN are declared as volatile because they could change without an assignment seen by the compiler.

Please also note that the compiler does not know that interrupt handlers can interrupt other functions, so it might not bother to re-read some variable that might have been changed by the interrupt. So variables that are shared between some interrupt handler and the main program must also be declared volatile.


By default, all GPIO pins are configured as inputs. These inputs are implemented with MOSFETs, and their gate is so small that it can pick up a random charge from any nearby signals, or even through the air, if you don't actively drive an input high or low. This is called a "floating input".

Even worse, an input that happens to be half charged switches both the "1" and the "0" connections half on, and there will flow a current from the power supply to ground.

The User's Guide says in section 12.2.8:

Configuring Unused Port Pins

Unused I/O pins should be configured as I/O function, output direction, and left unconnected on the PC board, to prevent a floating input and reduce power consumption. The value of the PxOUT bit is don't care, because the pin is unconnected. Alternatively, the integrated pullup/pulldown resistor can be enabled by setting the PxREN bit of the unused pin to prevent the floating input.

\$\endgroup\$
2
  • \$\begingroup\$ Making variables volatile so you can view them in the debugger is bad advice. Volatile has its purposes and this isn't one of them. This is a side effect of volatile. Instead, just turn off the optimizer. It's the direct and explicit resolution to the problem. When you're done debugging you may choose to turn the optimizer back on for code speed and size improvements. You wouldn't want to go back through your code and remove all the unnecessary volatiles at that point. \$\endgroup\$
    – kkrambo
    Commented Aug 6, 2015 at 13:36
  • \$\begingroup\$ This particular variable was introduced for debugging in the first place. \$\endgroup\$
    – CL.
    Commented Aug 6, 2015 at 13:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.