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!
Best Answer
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 theif((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
:Please note that all registers like
P2IN
are declared asvolatile
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: