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.