Electronics - MSP430 - Managing P1DIR and P1OUT registers to blink the red and green LEDs

This tutorial has to be seen as the most easy code that is possible to do with a MSP430 LaunchPad and then totally adapted for beginners.

Indeed, we are going to blink together the red and the green LEDs by explaining what we are doing with the famous P1DIR and P1OUT registers.

Ready?
So, let's do it!

Explanation

Good to know

In the MSP430 Launchpad there are a few microcontrollers possible to use.

For example, if you bought the LaunchPad recently, it could be a MSP430G2553, or older a MSP430G2221.
In this turorial we will use the MSP430G2553.

Anyway, the code below works for every microcontroller.

So, the first thing to know is that to blink a LED, we have to tell a special registry what we would like to do.

In our case, we would like to blink the red (pin 0) and the green (pin 6) LEDs.

You can check it directly on your board, at the bottom left, there are our two LEDs with P1.0 and P1.6 written respectively above the red and the green jumpers of the LEDs.

This P1DIR registry

OK, now that we have understood which LED is on pin 0 and 6, we are going to see which registry will help us to blink those LEDs.

This registry is P1DIR and it's a word of 8 bits.

It means that each bit of this word can be set to 0 or 1 and each bit is linked to a pin.

  • Low or 0 meaning that the pin is set as an input;
  • High or 1 meaning that the pin is set as an ouput.

So:

  • 0 (low) = input
  • 1 (high) = output

It's now easy to talk with the P1DIR and tell it which of pin we would like to set as ouputs.

We use ouputs because a LED as to be set like this to blink.

We have to use port 1 for our LEDs, so it will be the P1 output.

As our LEDs are on pin 0 and pin 6 we can say that we will be using the P1.0 and P1.6 pins.

And so, in our word of 8 bits, we have to set the bits we want to set as output (hence 1).

We have then to set P1DIR like this:

  • 01000001

P1.0 = first.
p1.6 = seventh.

We can see that the first bit (on the right) is set to 1 because we have to set the pin 0.
And then the sixth bit (from the right) is actually the seventh on the list.

At this point, the registry knows that pin 0 and pin 6 will be set at 1 and are expected to send data from the microcontroller to those pins.

The LEDs

The P1DIR registry knows which pins will be used as output.

But it doesn't know when to send data to them.

We have then to use the P1OUT regitry to do that.

Indeed, this registry is specially designed to tell the microcontroller when send data to a pin.

Those pins are the same as those used previously with the P1DIR registry, that is P0 and P6.

It's time to see the code.
Notice that BIT0 and BIT6 are defined respectively to hexadecimal numbers in the msp430g2553.h file:

  • #define BIT0                   (0x0001)
  • #define BIT6                   (0x0040)

In binary:

  • BIT0 = 00000001
  • BIT6 = 01000000

So BIT0 + BIT6 is equal to:

    00000001
|  01000000
----------------
= 01000001

Code

#include <msp430g2553.h>                      // change it with your microcontroller

void main() {
    WDTCTL = WDTPW | WDTHOLD;                 // don't touch it, it's for the watchdog stuff

    P1DIR |= (BIT0 | BIT6);                   // set P1DIR with P0 and P6 to high (1)

    for (;;) {
        P1OUT ^= (BIT0 | BIT6);               // toggle the P0 and P6 of P1OUT with 1 and 0
        __delay_cycles(250000);               // 250000 microseconds between each cycle
    }
}

Conclusion

In this tutorial you created your first example with the MSP430 LaunchPad and see how to use the P1DIR and P1OUT registers.

You are now able to blink the green and the red LEDs like a professional.

Well done, you made it. laugh

Comments

Comment: 

Why "|=" and not just "=" ?

Comment: 

Hello Otto Hunt,

I used "|=" instead of "=" because it's an usual way to program electronic microcontroller.

When you use "|=" it means that you are setting registers.

When you use "&=" it means that you are resetting registers.

I use "=" only when I program classic software in Java or PHP for example.

But in the tutorial's code, using "=" instead of "|=" is, indeed, the same. laugh

 

Comment: 

The primary reason to use |= is that it helps to make sure other bits of the registers are not affected by the assignment statement. Bitwise ORing enables not to change bits other than the target bit.

Comment: 

Hello Ambesaw,

You're absolutely right. yes

Comment: 

you can also do like this
P1DIR = BIT0 + BIT6;
while(1)
{ P1OUT ^= (BIT0 | BIT6); } // toggle the P0 and P6 of P1OUT with 1 and 0
__delay_cycles(250000);

Comment: 

Okay, so I get why you do this:
P1OUT ^= (BIT0 | BIT6);
It will keep toggling Pin0 and Pin6 with 1 and 0 in order to make the LED's blink.

But why do we have 2 Bitwise Or's?
P1DIR |= (BIT0 | BIT6);
I understand that Bit0 | Bit6 sets P1DIR to 01000001.
But what does the |= do? Does it do the actual assigning of P1DIR?

Thanks in advance.

Comment: 

Hello Pat,

Yes "P1DIR |= (BIT0 | BIT6);" sets the P1DIR to 01000001.

Setting P1DIR allows electricity to circulate through BIT 0 and BIT 6.

It's like in a house, you can switch on lights ONLY if there is electricity in your electric house circuit.

In our case, we say that we want electric current ONLY inside BIT ZERO and BIT SIX.

And after we decide with P1OUT to switch ON and OFF the BIT 0 and BIT 6.

For the "|=", it means that we change the value of BIT 0 and BIT 6 to "1".

Because:

  • 0 | 1 = 1
  • 1 | 1 = 1

So with this bitwise OR we set the corresponding bit to 1 whatever was the value before the assignment. cool

 

 

Comment: 

Hi Mi-K. Thank you very much for your answers; they helped a lot :) I do have a few more questions, though.

-Is P1OUT originally 00000000 ?

-And instead of doing P1OUT ^= (BIT0 | BIT6);
can we do P1OUT ~= (BIT0 | BIT6);

Will the complement inside a for loop work by continuously toggling Pin0 and Pin6 with 1 and 0 in order to make the LED's blink?

Comment: 

Hello,

1) We can never know if P1OUT is set to 0x00 or not.

So to be totally sure of that, best practice is to reset it before doing anything with it.

Same for P1DIR, I recommend to set it to 0x00 before anything else.

For example:

  • P1DIR &= 0x00;
  • P1OUT &= 0x00;

2) The following line isn’t correct:

  • P1OUT ~= (BIT0 | BIT6);

Because the "~=" operator doesn’t exist in C language.

3) The loop I made in the tutorial is infinite, so yes inside this "for loop" Pin0 and Pin6 continuously toggling.

cool

Comment: 

How can we make both LEDs blink alternatively? I mean "red on when green off" and red off green on" so on? Thanks

Comment: 

for (;;) {
// toggle bit 0 of P1
P1OUT ^= 0x01;
for (i = 0; i < 0x4000; i++);
P1OUT ^=0x40;

// delay for a while
// __delay_cycles(250000);
for (i = 0; i < 0x9000; i++);

Comment: 

I put 00000001 instead of bit1 but don't work
Can i ask what is the problem?

Comment: 

You can't use binary code directly in your C language code, use either equivalent in hexadecimal or the macros like BIT1, BIT2, etc. cool

Comment: 

How do you program the LED to go off when the button is pressed and stay on until the button is pressed again?

Comment: 

What code for only blink the green led in launchpad

Add new comment

Plain text

  • No HTML tags allowed.
  • Lines and paragraphs break automatically.