Search tips

# Embedded Systems Blogs > Enrico Garante > MSP430 Launchpad Tutorial - Part 1 - Basics

Enrico Garante (contact)
Enrico has received his Bachelor's degree in Electrical Engineering from the University of Rome "La Sapienza". After a six-months internship in Texas Instruments, he is n...show full bio

Would you like to be notified by email when Enrico Garante publishes a new blog?

Pageviews: 7544

# MSP430 Launchpad Tutorial - Part 1 - Basics

Posted by Enrico Garante on Jun 14 2013 under Tutorials | MSP430

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!

4

posted by Enrico Garante
Enrico has received his Bachelor's degree in Electrical Engineering from the University of Rome "La Sapienza". After a six-months internship in Texas Instruments, he is now studying for his master's degree in Electronic Systems.

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

Carlos
Said:
thanks for sharing.
1 year ago
+1
Sorry, you need javascript enabled to post any comments.
Richard84
Replied:
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.
8 months ago
0
Richard84
Replied:
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.
8 months ago
0
rohit30793
Said:
#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
12 months ago
0
Sorry, you need javascript enabled to post any comments.
egarante
Replied:
What errors are detected?
11 months ago
0
danvcs2
Said:
This worked good for me.

thanks,

awesome and informing tutorial
9 months ago
0
Sorry, you need javascript enabled to post any comments.
Richard84
Said:
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
8 months ago
0
Sorry, you need javascript enabled to post any comments.
Richard84
Replied:
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.
8 months ago
0
shaharasor87
Said:
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!
3 months ago
0
{"extraction_info": {"found_math": true, "script_math_tex": 0, "script_math_asciimath": 0, "math_annotations": 0, "math_alttext": 0, "mathml": 0, "mathjax_tag": 0, "mathjax_inline_tex": 0, "mathjax_display_tex": 0, "mathjax_asciimath": 1, "img_math": 0, "codecogs_latex": 0, "wp_latex": 0, "mimetex.cgi": 0, "/images/math/codecogs": 0, "mathtex.cgi": 0, "katex": 0, "math-container": 0, "wp-katex-eq": 0, "align": 0, "equation": 0, "x-ck12": 0, "texerror": 0, "math_score": 0.15360935032367706, "perplexity": 9338.033419604466}, "config": {"markdown_headings": true, "markdown_code": true, "boilerplate_config": {"ratio_threshold": 0.18, "absolute_threshold": 10, "end_threshold": 15, "enable": true}, "remove_buttons": true, "remove_image_figures": true, "remove_link_clusters": true, "table_config": {"min_rows": 2, "min_cols": 3, "format": "plain"}, "remove_chinese": true, "remove_edit_buttons": true, "extract_latex": true}, "warc_path": "s3://commoncrawl/crawl-data/CC-MAIN-2014-42/segments/1414119649807.55/warc/CC-MAIN-20141024030049-00161-ip-10-16-133-185.ec2.internal.warc.gz"}