MSP430 Launchpad Tutorial - Part 1 - Basics

So, let's see how to start a new project in Code Composer Studio. This IDE is derived from Eclipse, so if you used it before you shouldn't have much problems.

We'll write a simple program that will toggle a led when we press the on-board button.

Go to New->CCS Project

Give a name and a destination folder to your project, then click "Next". Be sure to select "MSP430" in the next window, then go ahead. Don't care about the "Additional Project Settings" window for now, and click "Next". In the "Project Settings" window, be sure to have everything set like this picture.

In the "Device Variant" field, select the correct MCU you have installed on your LaunchPad, then click "Finish".

Now we have to add a "main.c" file to our project. Right-click on your project name (note that it is in bold and has "Active - Debug" tags, meaning it will be the main project that will be compiled and debugged later on). Select "New->Source File".

Call it "main.c" then click finish. Now we are ready to add some real code!

Our first line of code will be this

#include "msp430g2231.h"  //Contains definitions for registers and built-in functions

With this we include the definitions of registers and built-in functions for the MSP430G2231 e.g. if you used the other chip, the G2211, you had to include"msp430g2211.h" header file.

Next, we have the main routine.

int main(void)  //Main program
{
WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer

P1DIR |= BIT0; // Set P1.0 to output and P1.3 to input direction
P1OUT &= ~BIT0; // set P1.0 to Off
P1IE |= BIT3; // P1.3 interrupt enabled
P1IFG &= ~BIT3; // P1.3 interrupt flag cleared

__bis_SR_register(GIE); // Enable all interrupts

while(1) //Loop forever, we'll do our job in the interrupt routine...
{}
}


It's quite a mere "setup" routine, as we don't do nothing that involves the led toggleing.

WDTCTL = WDTPW + WDTHOLD;


With this line, we stop the "Watchdog timer": it is typically used to reset the MCU after a certain amount of time, to prevent deadlocks and infinite loops. In most examples, you will see that the watchdog timer is stopped during the first line of code, to avoid unwanted resets.

P1DIR |= BIT0;


With this instruction, we set the P1.0 pin (which is connected to the red led on the LaunchPad) to the output direction. In the MSP430 architecture, P1DIR is a 8-bit register that controls the i/o direction of the Port 1 pins. If you set a bit to 0, it is configured as an input, otherwise it is an output. The BIT0 constant is simply the 0x01 hex number, so you do this :

P1DIR before        00000000+
BIT0                00000001=
P1DIR after         00000001


This way, all the Port1 pins are set to input direction, except for P1.0 which is our led.

P1OUT &= ~BIT0;

Whit this,we resetthe P1.0 output . In fact, the P1OUT register controls all the output pins: if you put a bit to 1 (by or-ing the P1OUT register with the right numeric constant BIT0, BIT1...), the relative output pin is set on HIGH logical level, otherwise (by and-ing the P1OUT register with the inverted numeric constant) it is set on a LOW level.

P1IE |= BIT3; // P1.3 interrupt enabled
P1IFG &= ~BIT3; // P1.3 interrupt flag cleared


With these two instruction, we enable the interrupt on the P1.3 input pin (the on-board button).
What is an interrupt? Well, this is not the rigth time, but for now I'll you only have to know that this two lines of code allows the chip to know when the button has been pressed, even if he is doing other things (like calculations, delays ecc...). The P1IE register is used to enable interrupts on an input pin (it works like the P1DIR e P1OUT registers), and the P1IFG register is used to know if the desired event (in this case the press of the button) has happened (then the relative bit is set to 1) or not (the bit is set to 0).

__bis_SR_register(GIE);


With this built-in function, we enable all the interrupts by setting the GIE (Global Interrupt Enable) bit in the Status Register of the MSP430G2231. This function is also used to enter Low-Power modes, but this will be covered in a future tutorial.

while(1) {}


Finally, we enter an infinite-loop, as we have nothing more to do in the main function.
In fact, we will actually toggle the led in the "Port 1 interrupt service routine". This routine is called every time the state of a interrupt-enabled P1 pin changes from high to low (the button on the LaunchPad is active-low).

#pragma vector=PORT1_VECTOR
__interrupt void Port_1(void)
{
P1OUT ^= BIT0;  // Toggle P1.0
P1IFG &= ~BIT3; // P1.3 interrupt flag cleared
}


The first line of this function (P1OUT ^= BIT0;) toggles the pin state by xor-ing it. Then the Interrupt flag is set back to 0 in order to listen for another interrupt.

Now we are ready to launch the code on CCS.
Be sure to have the LaunchPad connected to your PC, then press the little green-bug button on the IDE to compile, download the code and enter the debug perspective.

Then press the "Play" button to start execution, the "Stop" button to exit debugging and the "Chip" button to reset the board.

If everything went well, you should see that if you press the on-board button, the red led will turn on and off.
If so, congratulations! You have built your first MSP430 program!

Here's the complete code of this example:

#include "msp430g2231.h"  //Contains all definitions for registers and built-in functions
int main(void)  //Main program
{
WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer

P1DIR |= BIT0; // Set P1.0 to output and P1.3 to input direction
P1OUT &= ~BIT0; // set P1.0 to Off
P1IE |= BIT3; // P1.3 interrupt enabled
P1IFG &= ~BIT3; // P1.3 interrupt flag cleared

__bis_SR_register(GIE); // Enable all interrupts

while(1) //Loop forever, we'll do our job in the interrupt routine...
{}
}
#pragma vector=PORT1_VECTOR
__interrupt void Port_1(void)
{
P1OUT ^= BIT0;  // Toggle P1.0
P1IFG &= ~BIT3; // P1.3 interrupt flag cleared
}


That's all for now. The next tutorial will focus on Timers and Interrupts.

Happy Coding!

Next post by Enrico Garante:
MSP430 Launchpad Tutorial - Part 2 - Interrupts and timers

[ - ]
Comment by July 18, 2015
Hi! I translated the code for TI's MSP-EXP430F5529LP board, I hope it helps!

#include "msp430F5529.h" //Contains definitions for registers and built-in functions

int main(void) //Main program
{
WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer

P1DIR |= BIT0; // Set P1.0 to output
P1OUT &= ~BIT0; // set P1.0 to Off

P2DIR &= ~BIT1; // Set P2.1 to input
P2REN |= BIT1; // Enable pullup resistor of P2.1 (default: GND)
P2OUT |= BIT1; // Set pullup resistor to active (+3.3V) mode

P2IE |= BIT1; // P2.1 interrupt enabled
P2IFG &= ~BIT1; // P2.1 interrupt flag cleared

__bis_SR_register(GIE); // Enable all interrupts

while(1) //Loop forever, we'll do our job in the interrupt routine...
{}
}

#pragma vector=PORT2_VECTOR
__interrupt void Port_2(void)
{
P1OUT ^= BIT0; // Toggle P1.0
P2IFG &= ~BIT1; // P2.1 interrupt flag cleared
}
[ - ]
Comment by September 30, 2013
thanks for sharing.
[ - ]
Comment by February 20, 2014
Solved.
On my board there aren't mounted Rpull up and anti debouncing capacitor.
I add on code the pull up on the push button
P1REN |= BIT3; // Enable Pull Up on (P1.3)
, and I add (pheraps not necessary)
P1IES |= BIT3; // P1.3 Hi/lo edge
to select the interrupt activation' edge.
[ - ]
Comment by February 19, 2014
Hi Carlos, I see in tutorial "part 2" that you also have MSP430G2553 board.
Have you executed this 'part 1' code succesfully?
Thanks a lot.
[ - ]
Comment by November 19, 2014
Richard84, thank you so much.
Really.
I too am working with a 2553 and didn't know why I wasn't getting the expected result.

The pull up resistance fix is really waht I needed, thanks.
[ - ]
Comment by March 5, 2015
I want to interface SPI module with any IC in MSP30 microcontroller.That IC should support with SPI .BUt i dont know how to select the IC device. I want to send data and receive by using that Ic.Please riply
[ - ]
Comment by December 30, 2017

Nice beginner example.  It would be even better if the example worked.   Be sure to read the comments about adding the pull up resister to allow the button to work properly.    You'll still have button bounce problems, but that's ok for a simple example like this as long as you understand the erratic behavior is a bounce problem

[ - ]
Comment by November 8, 2013
#pragma vector=PORT1_VECTOR
__interrupt void Port_1(void)
{
P1OUT ^= BIT0; // Toggle P1.0
P1IFG &= ~BIT3; // P1.3 interrupt flag cleared
}
This code is showing syntax error and other declaration errors too...please correct it
[ - ]
Comment by November 29, 2013
What errors are detected?
[ - ]
Comment by January 25, 2014
This worked good for me.

thanks,

awesome and informing tutorial
[ - ]
Comment by February 19, 2014
Hi, I'm a good hw designer but a terrible newbie in Code C.

Red led is still on P1.0 and pushButton is still on P1.3.

If I move my finger near the button (near about 1mm or 2) the led change state, if I press the button with a plastic pen, nothing happens.

Could be the pin set as capacitive touch pin?
If yes, how can I disable it? (I try only to set to 0 control bit P1SEL and P2SEL)
If no, what it could be?

Nice article, good job! Thanks
[ - ]
Comment by February 20, 2014
Solved.
On my board there aren't mounted Rpull up and anti debouncing capacitor.
I add on code the pull up on the push button
P1REN |= BIT3; // Enable Pull Up on (P1.3)
, and I add (pheraps not necessary)
P1IES |= BIT3; // P1.3 Hi/lo edge
to select the interrupt activation' edge.
[ - ]
Comment by June 30, 2014
Thanks for the tutorial. i started with urs and then went to this tutorial. it can be a continuation of this one.
[ - ]
Comment by July 26, 2014
hi,
just purched MSP430F5529LP and i am trying to write a code using switch button.
in the following code a defined the switch as an input (P1.1 = 0 - by default)

void main()
{
WDTCTL = WDTPW + WDTHOLD; //stop watch dog timer
P1DIR |= 0x01; // red LED output
P1REN |= 0x02; //enable pullup/down

while(1)
{
//do something
}

}
somehow, as i debbuged this code, P1IN remains constant as i press the switch(P1IN doesnt change according to the switch pressing)
I am quiet lost about it cause i know that PxIN is readonlt register that gives indication about the inputs.

thanks!
[ - ]
Comment by March 5, 2015
Hi ,can anyone tell,I want to interface SPI module with any IC in MSP30 microcontroller.That IC should support with SPI .BUt i dont know how to select the IC device. I want to send data and receive by using that Ic.Please riply
[ - ]
Comment by July 4, 2015
As you can see, I'm using MSP430G2553 board, it isn't recognizing the push button press... Could someone help me?

Code:

#include

int main(void) {
WDTCTL = WDTPW | WDTHOLD; // Stop watchdog timer

P1DIR |= BIT6;
P1OUT &=~BIT6;

P1REN |= BIT3;
P1IE |= BIT3;
P1IFG &=~BIT3;
__bis_SR_register(GIE);

while(1){
}
}

#pragma vector=PORT1_VECTOR
__interrupt void Port_1(void){
P1OUT ^= BIT6;
P1IFG &=~BIT3;
}
[ - ]
Comment by September 22, 2017

Hello,

What does this line means?

#pragma vector=PORT1_VECTOR


And how does the MSP430 knows that it should jump to this function when the interrupt is set?

[ - ]
Comment by October 6, 2017

Thanks for sharing this tutorial. I m beginer and just little bit confusion about time about blinking of led as we have given infinite loop so how much it takes time in glow on and off?Because here we are not defining any clock or timer.

[ - ]
Comment by April 1, 2018

Friends send me the msp430 c-programm

1) Division of two numbers

2) Find largest element in array

3) BCD to ASCII and vice versa

4) ASCII to decimal and vice versa

5) hexa to decimal and vice versa

To post reply to a comment, click on the 'reply' button attached to each comment. To post a new comment (not a reply to a comment) check out the 'Write a Comment' tab at the top of the comments.