17 May 2010

Writing a first program

The typical "Hello, World!" of microcontrollers is a blinking LED. The F2132 target board has an LED connected to one of the pins on port 1 (P1.0, pin 21) by a jumper. Here's what a typical C program for this looks like:

/* blinkyF2132: test program toggling an LED connected to P1.0 on the
 * MSP430F2132.

#include <msp430x21x2.h>

void main(void) {

int i;

P1DIR = 0x01;
P1OUT = 0x00;

for (;;) {
P1OUT ^= 0x01;

for (i=0; i<0xFFFF; i++) {
} // delay
} // infinite loop

} // main

  • The first thing to note is the included header file; all msp430 compilers come with a collection of these files that define specific tools and behavior for the various families of the controllers. In this case, since I am using an F2132, I use the x21x2 family header. (Edit: looking at the header file included in CCS4, this format for the header file is considered legacy. The preferred usage would be specific to the chip itself, so in this case you would include the msp430f2132.h header file.)
  • WDTCTL, P1DIR, P1OUT and the like are all convenient keywords defined in the header file.
    • WDTCTL points to the word (2 bytes) controlling the watchdog timer. This timer resets the chip after a certain amount of time has passed. To keep our program running, it needs to be disabled. The 8 least significant bits (0 through 7) of WDTCTL control the behavior of the watchdog timer. Bit 7 specifically puts the timer on hold if set to 1. In the header file, WDTHOLD is defined to be a 2 byte value with only the 7th bit set to 1 (ie. 0b0000000010000000, or in hex, 0x0080). By writing WDTHOLD to WDTCTL, we turn off the timer.
    • WDTCTL only uses 1 byte for its control; the 8 most significant bits are set up as a key to prevent a program from inadvertently changing the configuration. Hence, to write to WDTCTL you need to include a password of sorts. This password is the value 0x5a, and the header defines WDTPW to be 0x5a00. By adding this value to WDTHOLD you end up writing the value 0x5a80 to WDTCTL--which satisfies the necessary key and sets the hold bit to 1. (Note that you could also use WDTPW | WDTHOLD instead of adding them. They have the same effect in this case, but the TI examples use +, so I chose to use that convention.)
    • Each port can configure each of its 8 pins to be inputs or outputs individually. On the target board, the LED is on P1.0, so P1DIR is set to have bit 0 to be the value 1 (output) and each of the other bits 0 (input). Writing 0x01 (0b00000001) to P1DIR configures it this way.
    • P1OUT controls the digital values on the output pins of P1. In this program, 0x00 sets the outputs all to zero, and 0x01 sets all but pin 0 to zero with pin 0 at 1. The LED is connected with its cathode at ground, so a high value on P1.0 turns on the LED. Thus 0x00 is off, 0x01 is on.
  • After setting up the configuration of the MCU, the program then enters the infinite loop: for (;;) { }. This step may seem odd at first, but since we want our controller to keep working, we can't have a program that terminates. Practically, without the loop the MCU would then continue trying to execute statements in the next memory spaces, eventually reading well beyond the actual program to unpredictable results.
  • Inside the infinite loop, the program changes the value on P1.0. The ^, which is the C symbol for the exclusive or operation, turns the LED on if it is off, and off if it is on. Another for loop causes a delay between toggles on the LED. The length of the delay depends on how far the iterator i has to count. (It also depends on the frequency at which the MCU is operating; a faster clock speed makes the iteration count faster.)

This program is very simple, and not really useful for much other than to reassure you that everything works right and that you can actually program the msp430. Below is a short video of my target board running the program. There are certainly more elegant ways to do this trivial task, but this method is a good way to start and doesn't require much understanding of the MCU itself.

Reader Exercise: Write a similar MSP430 program using the MSP430F2001 to alternate blinking LEDs on ports P1.2 and P1.7 (ie. LED 1 is on, LED 2 is off. After some time, they switch to LED 1 off, LED 2 on. The F2001 is a 14 pin MSP430 that comes in PDIP, TSSOP, and QFN packages. P1.2 is pin 4, P1.7 is pin 9.)


epidemicz said...

I just found this site, and have only done enough to write down the example code but I can already tell this is going to go a long way in helping me get started with my new launchpad. Thanks very much and I hope you keep adding more :D

Caleb Coffie said...

Hello I just started reading your blog and it's helping me a lot. Also you explain the code really well in your comments. One suggestion though, Could you provide an answer key to the Reader Exercise because I currently don't have my LaunchPad and have no way of testing to see if I did it correctly.

Iouri said...

There is another way to do delay (although similar one - cycle counting)

Ciufulet said...

"The LED is connected with its anode at ground, so a high value on P1.0 turns on the LED. Thus 0x00 is off, 0x01 is on."
The LED should not be with the Cathode at ground and Anode to the I/O pin??

Unknown said...

Oops.. fixed it. Thanks.

sourabh said...

hey dude, that's really a very good altruistic gesture from you. I appreciate it.

Maanasa said...

Just started and am already loving the blog! :)

afreen said...

Lovely...every step is explained accurately... Nice job...!