Electronics - MSP430 - Using P1OUT and P2OUT registers of the LaunchPad to manipulate LEDs with bit shifting

After creating a software to count in binary, let's see how bit shifting works.

In this tutorial we are going to see how to turn on and off a single LED each time we will be using the left bit shifting.

But what is interesting, in this video example, it's that we will be manipulate GPIOs with P1OUT and P2OUT registers.

Let's get started.

What do we need?

In order to have exactly the same example as in the video, let's see which electronic stuff we need:

  • 1 MSP430 LaunchPad with a M430G2553 microcontroller;
  • 14 LEDs (4 red and 5 orange, 6 green);
  • 14 resistors (1 of 22 kohm and 13 of 330 ohm);
  • 4 breadboards;
  • 43 wires (2 black, 4 tiny and 4 long orange, 9 green, 10 red and 14 yellow);
  • 1 USB mini cable.

Explanation

Before starting, I would like to tell you that the 22 kohm resistor is there only because the luminosity of my sixth green LED was to high with a 330 ohm one (I had only 5 same green LED).

This said, we can begin.

We would like to use the P1OUT and P2OUT registers to turn on and off a LED, successively, from P1.0 to P2.5.

Then only one LED will be turned at a time.

We start by P1OUT and we give it the value of BIT0.

Notice that BIT0 isn't equal to 0x000 but 0x001.

So the P1.0 pin will be set to high (1) and then the LED connected to this pin will be turned on.

We have then to turn off this first LED and turn on the second.

For that we will be use the left bit shift "<<" operator.

With it we will tell the P1OUT register to take the value on its right and multiply 2 exponant this value.

For example if we had this operation to understand:

P1OUT = 0x001 << 1

we could transform it by:

 P1OUT = 0x001 x 2^1.

and then have as result:

P1OUT = 0x002

Now if we had:

P1OUT = 0x008 << 4

we could transform it by:

P1OUT = 0x008 x 2^4

and the result would be:

P1OUT = 0x080

Notice one important thing there is that each time we have a "x" in a number, this number is an hexadecimal number.

So starting from 0 to F:

  • 0
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • A
  • B
  • C
  • D
  • E
  • F

Another important point is that 0x080 is then equal t0 128 in decimal.

Let's try to code a bit (OK nice pun!!).

The code

#include <msp430.h>

void delay_ms(unsigned int delay);

#define TIME_START 7

/**
* The main function.
* Notice that we don't need a return value.
* The function is thus of void type.
*/
void main(void) {
    WDTCTL = WDTPW | WDTHOLD;             // Stop watchdog timer

    P1DIR &= 0x00;                        // resetting the P1DIR registers
    P2DIR &= 0x00;                        // resetting the P2DIR registers

    P1DIR = 0xFF;                        // setting all the P1DIR registers to 1 (high)
    P2DIR = 0xFF;                        // setting all the P2DIR registers to 1 (high)

    P1OUT &= 0x00;                        // resetting the P1OUT registers
    P2OUT &= 0x00;                        // resetting the P2OUT registers

    P1OUT = BIT0;                        // setting the P1OUT registers to 0x0001

    while (1337) {                        // infinite loop
        if (P1OUT == BIT7) {
            P1OUT = 0x00;
            P2OUT = BIT0;                // setting the P2OUT registers to 0x0001
            while (P2OUT != BIT5) {
                delay_ms(TIME_START);                // delay
                P2OUT = P2OUT << 1;
            }
            delay_ms(TIME_START);                // delay
            P2OUT = 0x00;
            P1OUT = BIT0;
        }
        P1OUT = P1OUT << 1;
        delay_ms(TIME_START);                // delay
    }
}

/**
* Takes a value in parameter in order to have a delay.
* 16,000 is equal to 16,000,000 / 1,000.
* -> 16,000,0000 = 16MHz (the CPU clock speed).
*/
void delay_ms(unsigned int delay)
{
    while (delay--)
    {
        __delay_cycles(16000);
    }
}

Conclusion

This kind of exercise is essential to understand hardware systems and learn how to manipulate them.

I recommend you changing data in the code in order to get subtleties.

Once again, great job, you've just made it. cool

Comments

Comment: 

Great exercise, this is just enough to get me started on my build, working with an outdoor display control for 120V strings. If I can get the code worked out then I can move up from the counter/ dividers and sensing parts to a point.

Comment: 

This is great. The only thing I don't understand from the code is where does the 1337 in the while loop come from.

Comment: 

Hello Jenny,

In C language (and many others) when you are in a loop, if the variable you are testing becomes zero, then you go outside the loop.

In the code 1337 is like 1, -59, 34343, -9999, meaning that you can write the value you want except zero if you want to have an infinite loop.

So to be short, you can replace 1337 by 1. laugh

Comment: 

Hello,

I have a question about how to use P1OUT and P2OUT. If I'm using P1.5, and P2.0, they're both on the same side of the micro controller, would this constitute using P1OUT for both of those pins, or is P1.5 for P1OUT, and P2.0 used with P2OUT? I'm trying to figure out when to use certain port outputs based on certain pins being used...is it based off of the first number on the pin label, or the specific side of the micro controller?

Thanks for answering in advance!

Comment: 

Hello Branson,

P1 and P2 are both ports.

But they are not linked, they are independant.

It means that if you want to play with the Port 1 (P1) and activate it only, you won't be able to use pins of Port 2.

To use pins of a port, you have to activate it.

They are on the same side because it was certainly easier for the board designers to create it.

laugh

Add new comment

Plain text

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