Professional Documents
Culture Documents
1. Take a look at the bottom left corner of your Launchpad. There is a white button, and if you look
carefully, you can see it is labeled as P1.1 S1.
In this handout, we will see how this pushbutton is connected to the microcontroller, how it
works, and finally, how we can use it in our programs.
A BIG CAUTIONARY NOTE. This handout is not short, and it probably has some of the most
complex hardware-software interactions we will discuss throughout the course. Please be patient
as you work your way through the handout. If you want to skip ahead and see how the program
runs on your board, jump ahead to step 11 and copy the program into a new project and try it out.
The program will turn on the red LED as long as the P1.1 pushbutton (lower left corner) is held
down. As you go, be patient. Most students take a while to get through this, and please let us
know how we can help.
P1.1 Pushbutton
P1.1 S1 Label
The component name and number start with an S, which is an abbreviation for switch.
The component name ends with a 1, because it is the first switch on the board as it was designed.
If you look carefully, in the lower right corner, you can find switch S2, and near the top left, you
can find switch S3.
3. Next, remember that the microcontroller has metallic pins to connect it to the outside world. You
can see a magnified shot of the pins below.
In addition, if you look carefully, you can see different colored lines on the plastic board
extending out from the pins. The lines are called “traces.” These traces are actually small
metallic wires that form the electrical connections between the microcontroller and the outside
world.
Board Traces
Microcontroller Pins
4. The microcontroller pins that connect to the outside world are arranged in ports, with each port
containing 8 pins.
For example, port 1 has 8 pins. The pins are numbered 0, 1, 2, 3, 4, 5, 6, and 7. (Engineers like
to start counting at zero.)
The P1.1 pushbutton is connected to pin 1 of port 1. This is often abbreviated as P1.1, where the
first digit is for the port and the second digit is for the pin on the port.
6. Before we move on, take a look at all the rest of the pin labels on the board. Most of the labels
tell you which microcontroller port pin the point is connected to. For example, P4.7 is
connected to pin 7 of port 4.
Below is an electrical schematic that shows how the button is connected to the microcontroller.
The switch is shown as a “swinging door” that is open. An arrow shows that even though the
switch is normally open (no electrical connection through the switch), the switch can be pushed
closed to form an electrical connection. However, once the pushbutton switch is released, the
switch will swing open again removing the electrical connection.
The switch is connected to microcontroller pin P1.1 on one end, and the switch is connected to
an electrical ground connection on the other end. Electrical ground is referred to as a 0V (read as
zero volts) potential. Therefore, a switch connecting a pin to electrical ground like this is referred
to as a low-side switch.
P1.1
Microcontroller
S1
Electrical ground
8. When the button is pressed, and electrical connection is made between pin P1.1 and the
electrical ground. This connects the pin to the 0V ground. As you might expect from the digital
logic video and handouts, 0V is regarded as FALSE, NO, NOT TRUE, LO, or a logic 0 value.
For this reason, the switch needs a little help from the microcontroller. We want to make sure
that when the button is not pressed, and the pin P1.1 is not connected to a logic 0 electrical
ground that it is connected to a TRUE, YES, HI, and/or logic 1 value.
To do this, our program will tell the microcontroller to make an internal connection between the
pin and the power supply. (For those of you with an engineering or physics background, the
microcontroller inserts a resistor between the pin and the power supply. The resistor is called a
pull-up resistor because it “pulls” the P1.1 pin voltage HI.)
Now, when the pushbutton switch is open, the P1.1 pin is connected to a logic 1 value, but when
the pushbutton is pushed (and held) closed, the P1.1 pin is connected to a logic 0 value.
3.3V
P1.1
Microcontroller
S1
Electrical ground
11. Below is the first program that will make use of the P1.1 pushbutton switch.
#include <msp430.h>
main()
{
WDTCTL = DEVELOPMENT; // Need for development mode
12. The first line of the program includes another file, msp430.h , along with the main.c file when
your project is built. The msp430.h file tells CCS how the names in your program (like P1DIR
and P1OUT) are used by your microcontroller.
14. Next, we get to main() and the start of the actual program. (Everything else is generally called
pre-processor statements.)
As we have seen before, we begin the program by telling the watchdog security system we are
still developing code. We will look at the watchdog in more detail in a couple more sections.
15. In the next instruction, the microcontroller is essentially preparing its pins to be inputs and
outputs (commonly abbreviated as I/O or simply IO). Whenever we use the MSP430FR6989
microcontroller inputs and outputs, we will use this instruction.
16. The next instructions is used to specify that the microcontroller pin connected to the red LED
will be an output.
Any time we use one our pins as outputs, we will need to use a statement like this. All of the pins
are initially defaulted to be inputs.
As we said before, all of the microcontroller input and output pins are arranged in ports. Each
port has a direction register:
18. Let’s look back at one of the #define statements at the beginning of the program:
We defined the RED_LED label to correspond to the hexadecimal number 0x01. If we write this
number as a binary number, we get:
20. Think of P1DIR and any other 8-bit register memory location as a long rectangular box with 8
bins inside of it. The bins are numbered 0 to 7 (remembering that engineers like to start counting
at 0).
22. Looking back at the instruction, we are loading the binary number 00000001B into the P1DIR
register. This looks like:
23. When a bin in the P1DIR has a 0 in it, the corresponding pin will be an input.
When a bin in the P1DIR has a 1 in it, the corresponding pin will be an output.
Therefore, when P1DIR = 00000001B, pin P1.0 will be an output, and pins P1.1, P1.2, P1.3,
P1.4, P1.5, P1.6, and P1.7 will all be inputs.
25. Let’s take a look at one more example. Which pins on port 3 would be outputs if the P3DIR
register had this value?
We will show you the answer on the next page of the handout. Don’t look until you try to figure
the answer out yourself. : )
To load this example value into the P3DIR register, we could use any of the following
instructions:
To make this easier to read, some people even use more #define statements:
P3DIR = BIT7 + BIT4 + BIT1 + BIT0; // P3.0, P3.1, P3.4, P3.7 outputs
27. Let’s go back to our program. We are going to look at the next two instructions together because
they work in conjunction to perform one task.
29. Remembering that 0x02 in hexadecimal is the same thing as 0000 0010 in binary, we can
imagine that the P1OUT and P1REN register boxes would look like this.
P1OUT
P1REN
30. Notice how only pin/bin 1 of both registers is a 1 (or HI). This tells us that something is
happening on pin 1 of the port.
In the previous instruction, we had loaded 0000 0001 into the P1 DIRection register which left
pin 1 on port 1 as an input.
When a pin is configure as an input with its direction register (P1DIR), AND its pin/bin values are
1 in both the P1OUT and P1REN register, then the microcontroller will enable the pull-up resistor
that we talked about way back in step 9.
Wow. That’s a little bit tricky. To enable the pull-up resistor for a pushbutton switch on the
MSP430FR6989 microcontroller, we actually need to have three separate instructions. For
example, if we wanted to use a pull-up resistor for a push-button switch on pin P1.2, we would
need to have the following three instructions. Note, the bits corresponding to pin P1.2 are
indicated in the box.
32. Now, you might be asking yourself, why do we need all three of these instructions to configure a
pin to use a pull-up resistor?
The easiest way to answer that question is to realize how incredibly powerful microcontrollers
are. That little computer chip on your board was designed to do thousands of different tasks
using all of its different internal parts. While it might seem conceivable that each task could have
its own instruction, it does not work out that well in practice.
Most microcontrollers used today are very, very flexible devices that try to give you many, many
different features using a relatively small mix of instructions that can be combined in different
ways to get it to perform your desired task.
This class is going to teach you about microcontrollers and the C programming language, and we
are going to cover a lot of topics. However, to become a master at using a microcontroller would
require years of work and study. Such professionals are very highly regarded in the professional
community and their work is well rewarded.
For now, we are going to move on, but we do want you to know that we are going to try to show
you as many of these instruction combinations as we can to make you as proficient in
microcontrollers as we can.
The rest of the program will be taking place in an infinite while(1) loop. That way, the
microcontroller will keep responding to button pushes until you stop its program.
We have repeated the while(1) loop below with its comments. However, we have not shown the
actual C instructions yet – we want to add them one at a time. Each one is going to add one more
tool to our C programming tool box.
34. Now, let’s look at the first instruction inside the while(1) loop. It is determining if the P1.1
button is pushed, but it will probably seem a little strange when you first look at it….
First, realize that we are setting up another while loop. Like any other while loop, it will have a
condition that must be tested to see if the program goes into the loop, or continues on to the next
instruction.
The condition must be true (non-zero) to go into the loop and execute the instructions inside of
the curly braces before returning to the top of the while loop and re-evaluating the condition.
36. Let’s start with the right side of the condition, and work our way to the left. We are going to test
something with the == operator, we are going to test if something is zero.
( something ) == 0
If the something is zero, then the condition will be true, and the program will go into this inner
while loop.
However, if something is non-zero, then the condition will be false, and the program will skip
everything inside of the curly braces.
Looking back at the #define statements at the beginning of the program, we see again that
BUTTON11 is just the name we are giving to the hexadecimal number 0x02. (Again, 0x02 in
hexadecimal is 00000010 in binary.
BUTTON11
38. Next, P1IN is an 8-bit register “box” that has 8 bins, each one corresponding to one of the port 1
pins.
P1IN
40. This is where the power of the condition statement becomes evident.
We are going to bit-wise AND the contents of BUTTON11 and the P1IN values. To see this more
clearly, we are repeating their register boxes here again.
Each binary bit in the BUTTON11 box is going to be bit-wise ANDed with its corresponding bit in
the P1IN box.
BUTTON11
Bit-wise AND
Bit-wise AND
Bit-wise AND
Bit-wise AND
Bit-wise AND
Bit-wise AND
Bit-wise AND
P1IN
BUTTON11
Bit-wise AND
Bit-wise AND
Bit-wise AND
Bit-wise AND
Bit-wise AND
Bit-wise AND
Bit-wise AND
Pin 7 Pin 6 Pin 5 Pin 4 Pin 3 Pin 2 Pin 1 Pin 0
P1IN
"Result"
Therefore, since seven of the bits in BUTTON11 are 0, the result will have at least seven 0 bits also.
This means that the results will either be zero or non-zero depending on what happens with the
value of pin 1 in P1IN.
BUTTON11
Bit-wise AND
Bit-wise AND
Bit-wise AND
Bit-wise AND
Bit-wise AND
Bit-wise AND
Bit-wise AND
P1IN
From our truth table, when something is ANDed with a logic HI value, the result will be the other
value:
Therefore, if P1IN.1 is HI, Result.1 will be HI, and P1IN will be non-zero.
When the S1 push-button is pressed, then pin P1.1 is pulled to electrical ground.
This means a logic 0 will be on the pin, and P1IN.1 will also be 0.
When P1IN.1 is 0, the result of the bit-wise AND will be 0.
The condition is testing if the bit-wise result is 0, so the result will be true, and the program will
go into the loop when the button is pushed.
When the S1 push-button is NOT pressed, then pin P1.1 is pulled to the 3.3V supply voltage.
This means a logic 1 will be on the pin, and P1IN.1 will also be 1.
When P1IN.1 is 1, the result of the bit-wise AND will be 1.
The condition is testing if the bit-wise result is 1, so the result will be false, and the program will
NOT go into the loop when the button is NOT pushed.
3.3V
P1.1
Microcontroller
S1
Electrical ground
Some students gloss right through this idea, but they are very few in number. Most individuals
will struggle through these last few pages, and may need to go back through them a couple times.
In my 25 year career, I have seen expert programmers analyze statements like this for a long time.
Because there is so much happening in that one line of code, it is very, very easy to
misunderstand it. Be patient. When you feel comfortable with what we just went through, you
just mastered the most difficult part of the course.
If you have questions at this point, let us know. We want to help you be successful.
47. Now, let’s look at the line of code inside of the push-button test while loop.
We have to use the logic OR operation to set the P1OUT bit 0 (P1OUT.0) HI to turn on the LED
without interfering with a previous instruction:
P1OUT = BUTTON11;
P1REN = BUTTON11; We do not want the second
P1OUT instruction to undo the
while(1)
{
previous P1OUT operation.
while((BUTTON11 & P1IN) == 0)
{
P1OUT = P1OUT | RED_LED;
}
49. Below, we have shown you the P1OUT and the RED_LED boxes.
Recall, P1OUT has a value of 00000010 binary from its previous instruction.
P1OUT
RED_LED
00000010 P1OUT
| 00000001 RED_LED
----------
00000011 which will be stored in P1OUT.
This not only turns on the red LED connected to pin P1.0, but it also keeps the P1.1 pull-up
resistor in place.
52. Looking back at the last couple of lines of the program we looked at, we can see that as long as
the push-button is pressed, the condition of the while loop will be true, and the program will
continue into the curly braces to keep making sure that the red LED is turned on.
54. Again, this line is going to use a logic operator (bit-wise AND) to clear bit 0 of the P1OUT register
box without affecting the pull-up resistor associated with bit 1 of P1OUT.
Note, we cannot tell for sure what the contents of bit 0 of P1OUT will be at this point. It may
have already been turned on (and P1OUT.0 will be HI) or it could still be turned off (P1OUT.0
will be LO).
Regardless of the previous value of P1OUT.0, this operation will make it LO to ensure the red
LED is off.
P1OUT
CLEAR_RED_LED
56. Again, we are bit-wise ANDing the two together. Because the first seven bits (or pins) of
CLEAR_RED_LED are HI, the result will simply be the same values already stored in the first seven
bits of P1OUT.
However, because bit 0 is LO in CLEAR_RED_LED, the result will force P1OUT.0 to also be LO.
This ensures that every time that the push-button is not pressed, the red LED is forced off.
Once you feel comfortable with this, you are really on your way!
58. Copy the program and paste it into a new CCS project. After you run (Resume) the program in the
Debugger, you will see that the program will turn on the red LED whenever the push-button is
pressed and held down.
You can always explore the program more deeply by going line-by-line through the program with
Step Into in the Debugger.
59. Below, is a program that will turn the green LED on (lower right corner) with the P1.2 push-
button (also lower right hand corner). Note, the green LED is connected to pin 7 of port 9, so you
will see references to P9DIR and P9OUT when we are turning on and off the LED.
#include <msp430.h>
main()
{
WDTCTL = DEVELOPMENT; // Need for development mode
In no event shall the owner or contributors to the tutorials and software be liable
for any direct, indirect, incidental, special, exemplary, or consequential damages
(including, but not limited to, procurement of substitute goods or services; loss of
use, data, or profits; or business interruption) however caused and on any theory
of liability, whether in contract, strict liability, or tort (including negligence or
otherwise) arising in any way out of the use of this software, even if advised of
the possibility of such damage.