ee40/100 lab lab 6: microcontroller input/output …tkg/ee100_42_f09/...ports p1 and p2 are digital...
TRANSCRIPT
UC Berkeley, EECS Department
EE40/100 Lab Lab 6: Microcontroller Input/Output Summer 2009
1
Microcontrollers
Microcontrollers are very much slimmed down computers. No disks, no virtual memory, no operating system. Think of
them just like other circuit components with the added benefit of being configurable with a program. Because of this,
microcontrollers can be coaxed to do all sorts of things easily that otherwise would require a large number of parts.
Simple microcontrollers cost less than a dollar and hence can be used in almost any project. Indeed they can be found in
toys, electric tooth brushes, appliances, cars, phones, electronic keys; you name it.
Being programmable also means that they must be programmed. In this lab we concentrate on the electrical interface of
microcontrollers and their use as electronic components. The programs we use are very simple and consist to a large
part of pasting snippets of code together. In fact, much like checking the application notes of electronic components for
circuits that do what we need, it’s always a good idea to search the web for code that performs the job we need or is at
least a good starting point. Most of the code snippets shown in these lab guides are copies of code from the
manufacturer’s website. Feel free to improve on the example programs.
Microcontrollers are available from many manufacturers, all with their own advantages (and quirks). In this course we
use the MSP430 from Texas Instruments whose strengths are low power dissipation and a regular instruction set.
Figure 1 shows the architecture of the MSP430 line (specifically the model MSP430F2012; we will be using the more
complex MSP430F5438). The CPU block is the part that actually performs computations (e.g. additions). Note that
microcontrollers usually lack hardware for multiplication or division. These operations can be emulated in software,
albeit at the price of low execution speed. The clock system sets the operating speed (18MHz maximum for the
controller we are using, compare this to 2GHz or so for present day laptops). A 555-timer like clock is built right into the
chip; alternatively an external oscillator can be used if higher precision is required.
Flash is a nonvolatile memory for storing programs and
configuration data. RAM is where temporary variables go.
Note again the contrast to full blown computers:
microcontroller memory is typically a few kBytes flash and
a few hundred Bytes RAM. Most laptops today have at
least a GByte RAM (a million kBytes). You don’t need this in
an electrical tooth brush. JTAG and Spy-Bi Wire are nifty
interfaces for programming and debugging (the
microcontroller has no keyboard or LCD display). We will
use this interface to talk to the controller though USB from
a desktop computer and program the Flash memory. The
Spy-Bi Wire interface is used only for development once
completed the controller works standalone from the
program stored in the nonvolatile Flash memory.
The really interesting parts are the peripherals. Ports P1
and P2 are digital I/O buses that can be configured as
Figure 1 - Block diagram of the MSP430 microcontroller. In addition to
the processing unit (CPU), clock, and programming interface (Spy-Bi
Wire), the chip includes program (Flash) and data (RAM) memory,
digital inputs and outputs (Ports P1 and P2), Timers, and analog-to-
digital converter (ADC).
UC Berkeley, EECS Department
EE40/100 Lab Lab 6: Microcontroller Input/Output Summer 2009
2
inputs or outputs. They can be used for simple I/O with switches or LEDs;
in later labs we will see much more sophisticated uses of this simple
interface. Another block we will use is the ADC, an analog-to-digital
converter that serves as a bridge between the usually analog “real”
world and the microcontroller. For example we can use it to interface
the strain gage circuit designed in an earlier lab to the microcontroller
and make a full blown (simple) balance with display out of the
combination!
In this laboratory we are using a fairly powerful MSP430, the
MSP430F5438. Despite its large number of pins, there are no separate
pins for the ADC. Instead, some digital IO pins can be reprogrammed as
ADC inputs as needed. Several dozen MSP430 microcontrollers are
available with their main difference being the number of pins and the amount of memory. This permits you to start with
a small version, and as the project grows move to versions with additional memory or pins without having to change the
programs developed for the smaller
parts.
The specialized board shown in
Figure 3 makes working the
microcontroller hardware very
simple. Many forms of I/O are
provided, from simple buttons and
LEDs to graphics and sound. Even
serial communication with a
computer is readily available.
In addition to the microcontroller,
the board features a header along
the top edge for interfacing with a
ribbon cable to the USB interface
which will also supply power to the
board. Another header below that
one provides access to all eight bits
of port P10. A third header strip on
the bottom edge of the board
provides various pins from many
ports, each capable of digital I/O
but some capable of ADC input or
other functions.
The first two pins of port P1, P1.0
and P1.1, are permanently
Figure 2 - MSP430F2012 pin diagram. The MSP430
comes in many versions that include different amounts
of Flash and RAM memory and combinations of
input/output ports and other peripherals. Here we use
a very small version with only 14 pin that costs less
than a dollar in quantity.
Figure 3 - Picture of the microcontroller prototyping board used in this laboratory. In addition to the
MSP430, the board features two LEDs (connected to I/O port P1), a microphone, a headphone jack,
an LCD display, and seven button inputs (connected to I/O port P2). We can do many things with the
components on the board, and the MSP430 can communicated off-board using the pins on the I/O
connection headers.
UC Berkeley, EECS Department
EE40/100 Lab Lab 6: Microcontroller Input/Output Summer 2009
3
connected to on-board LEDs. These pins are not connected to any header, so there is no potential conflict of function,
but the pins must be configured as digital outputs for the LEDs to work.
Digital Output (Flashing Light) In this laboratory we will familiarize ourselves with the microcontroller board and the MSP430 development tool. We
will start with writing the classic “Hello World” example, which for a microcontroller is a blinking light.
1. Connect the microcontroller PCB to the MSP430 USB-Debug-Interface (MSP-FET430UIF). Use a standard USB cable
to connect the debug interface to a computer with the “IAR Embedded Workbench IDE” software. This software is
installed on the computers in the laboratory. Alternatively you can download it from the IAR website and install on
your own computer.
2. Start the IAR Embedded Workbench IDE. Choose “Create new project in current workspace”. A dialog with options
appears. We will write our program in the C language. Expand that choice, click on “main” and then click “OK”. The
program asks you to name your project. Call it “blink”. Hit enter.
3. Your screen looks as shown below, with a program already partially written.
4. Before finishing our program we need to configure the tool for the MSP430F5438. Choose the menu
“Project→Options…” and click on the “General Options” tab. Set “Device” as shown in the screen below by clicking
on the button to the right of the field and navigating the choices.
UC Berkeley, EECS Department
EE40/100 Lab Lab 6: Microcontroller Input/Output Summer 2009
4
5. Still in the options dialog, verify under the “Debugger” tab that the driver is set to “FET Debugger”. Also make sure
that under the “FET Debugger” tab “Connection” is set to “Texas Instrument USB-IF”.
Click OK.
uC
P1.0
330 Ohm
LED
Figure 4 - Circuit diagram for connecting an
LED to a microcontroller output port. The
resistor is needed since LEDs behave like
diodes with very large current flowing for
voltages above a threshold (around 1 V).
The microcontroller output changes
between 0 V and the supply voltage (around
3 V) for logic low and high, respectively.
Without the resistor a large current flows.
This can result in either the microcontroller
port or the LED to burn out.
UC Berkeley, EECS Department
EE40/100 Lab Lab 6: Microcontroller Input/Output Summer 2009
5
Now we write the program that turns P1.0 on and off.
1. First we need to configure P1.0 as a digital output using the following instructions:
P1OUT &= ~BIT0; // P1.0 low (LED Off)
P1SEL &= ~BIT0; // configure P1.0 for digital I/O
P1DIR |= BIT0; // configure P1.0 as output
The first statement sets the output to zero. It is not strictly needed here since we do not care if the LED is on or off
when the microcontroller starts. However it is a good idea to always first set an output to a known state before
enabling it, to avoid potentially disastrous failures.
The next two statements configure P1.0 as digital IO with direction set to output. As you would expect, the same
statements with BIT1 substituted for BIT0 enable P1.1 as output.
Put these statements just after the code that disables the watchdog timer (don’t worry about that timer; just make
sure the code is there to turn it off).
2. The following statements set the output low or high, or toggle its state:
P1OUT &= ~BIT0; // P1.0 low P1OUT |= BIT0; // P1.0 high P1OUT ^= BIT0; // P1.0 toggle
Text after // is treated as comment and there only for documentation. If you have ever taken a programming
course you know that we are supposed to document our code but few of us actually do it. Join the few.
3. The toggle version of the above statements is appropriate for blinking a light. Since we want to do this repeatedly
we enclose the statement in a loop:
for (;;) { // c-parlance for infinite loop P1OUT ^= BIT0; // toggle P1.0
} // closing bracket for infinite loop
4. The complete program looks as follows:
UC Berkeley, EECS Department
EE40/100 Lab Lab 6: Microcontroller Input/Output Summer 2009
6
5. Compile it by clicking on the second button from the right in the toolbar. Carefully examine possible error messages
(or ignore them and waste lots of time in frustration). A new window pops up:
Click the button (2nd
row in the toolbars). When done you can stop the program by clicking or modify the code and
click to recompile and restart with .
6. If everything went right the light turns on but doesn’t blink. At best it is a little dimmer than the Power LED. The
reason is that the microcontroller turns the LED on and off a few million times per second, too fast for our eyes to
follow.
7. The simplest fix is to give the microcontroller a bit of extra work to slow it down. Microcontrollers cannot get bored
and hence do not mind. Since we will often have need for such delays, we package this function in a subroutine that
we can easily reuse in other programs. Here is the code:
void delay(unsigned int n) { while (n > 0) n--;
}
Calling this code with the statement:
delay(30000);
causes the microprocessor to spin 30,000 times in a loop, decrementing the variable n each time around.
8. Let’s try this in our program:
UC Berkeley, EECS Department
EE40/100 Lab Lab 6: Microcontroller Input/Output Summer 2009
7
9. You can change the rate of the blinking by varying the argument to delay. Beware: the maximum permitted value is
a little over 65,000 (you’ll get a warning if you exceed the maximum which you are free to ignore if you need a few
hours of frustration with stuff that does not work). For longer delays you can e.g. use several delay statements. Can
you get the LED to blink at a rate of 1Hz?
If you paid attention the answer to this question is trivial: Assuming P1.0 has been configured as an output, what is the
code to set it to ���?
1 ��.0
Show your light to the GSI.
Analog Output So far we have used the microcontroller to turn an LED on or off. Frequently an “analog” output is required, i.e. a
voltage can assume any value between the supplies. Some microcontrollers contain special peripherals called digital-to-
analog converters (DACs) for this purpose. The model we are using lacks this feature. However, we can emulate an
analog output with a digital output by rapidly switching its value between the supply voltage and ground and adjusting
the relative times the output is high and low. For example, if the output is high (��� = 3 �) during 3 clock cycles and
then low (0 �) during 2 cycles, the average value of the output is �� ��� = 1.8 �. Likewise, if the output stays high for 21
cycles and low for 77, the average output voltage is
UC Berkeley, EECS Department
EE40/100 Lab Lab 6: Microcontroller Input/Output Summer 2009
8
1 ��.1
Write a subroutine function dac(n) that sets port P10.0 high during n cycles and low during 256-n cycles. (We cannot
use port P1.0 as we have been because it is permanently connected to the LED, so convert all mentions of P1 into P10,
e.g. P1OUT to P10OUT.) Here is a start:
void dac(unsigned int n) { ... set output high ... delay(n) ... set output low ... delay(256-n)
}
Call this function from your main program in an endless loop. Write your completed code into the box below:
1 ��.2
Test your “DAC” in the laboratory. First verify with the oscilloscope that for n=0 the output remains low (why is there a
“glitch” and how could you eliminate it?), and for n=256 the output remains high (except for a brief glitch). Then connect
a first order RC filter with � = 10 �٠and � = 10 �� to the microcontroller output and record the voltage �� across the
resistor on the oscilloscope. Adjust n such that �� = 1.3 � and ask the GSI to verify your result.
One drawback of this DAC is that it keeps the microcontroller busy and unavailable to do other tasks. A better solution
uses the microcontroller’s timer combined with a feature called interrupt to implement the delay. With this technique,
the dac function can run concurrently with other functions. We will not explore this feature here; please check the
manual and sample programs (see vendor website) for more information.
Digital Input Now we will focus on the second half of IO: inputs. In this section, we’ll be using the leftmost button (S1, connected to
P2.6) for the digital input to control the state of the LED.
Figure 5 shows the circuit for connecting a button to the microcontroller. Normally P2.6 is pulled to ��� (high) by the
pull-up resistor ���; pressing the button pulls P2.6 low. The circuit is even simpler than this since the microcontroller
UC Berkeley, EECS Department
EE40/100 Lab Lab 6: Microcontroller Input/Output Summer 2009
9
has a built-in ���; we just need to enable it. The connections on the board only place a
button between P2.6 and ground. Here is the code for enabling P2.6 as an input with
the pull-up resistor enabled:
P2OUT = BIT6; P2DIR = 0xbf; P2REN = BIT6;
The following statement checks for P2.6 to go low:
while (P2IN & BIT6); // wait for P2.6 to go low
Put this into the infinite loop to control the LED on P1.0.
Put your code for the button turning on the LED in the box below:
1 ��.3
Ask the GSI to verify the bar graph and button.
Assuming P1.5 has been configured as an output; what is the code to set it to GND?
1 ��.4
Analog Input Microcontrollers (and computers in general, for that matter) operate with digital data. However, many “real world
signals” such as temperature are analog in nature. An analog-to-digital converter is needed to input such signals into a
microcontroller. Analog-to-digital converters, or ADCs for short, are available as standalone electronic components or
built into more complex devices. Fortunately our microcontroller has an ADC built in. In this laboratory we will use this
ADC to interface the weight scale designed in an earlier laboratory to the microcontroller and have the bar graph display
the number of weights put on the scale.
uC
Rup
Push
Button
VCC
P2.6
GND
Figure 5 - Circuit for digital push-
button input
UC Berkeley, EECS Department
EE40/100 Lab Lab 6: Microcontroller Input/Output Summer 2009
10
ADCs compare an analog input ��, e.g. 1.387 �, to a reference voltage ���� to produce a digital number representing the
ratio of the analog input to the reference rounded to the nearest integer. For example, the ADC in our microcontroller
converts analog voltages to digital numbers according to the following equation:
� = !"�# $1023 × ������&
For example, with ���� = 3 � and �� = 1.387 �, � = 473. Negative input voltages and inputs exceeding the reference
produce are clipped to zero and 1023, respectively.
The program skeleton below shows the code for using the ADC and configures P6.7 as its input. Conversion results are
stored in the variable ADC12MEM0.
#include "msp430x54x.h" int main( void ) {
// Stop watchdog timer to prevent time out reset WDTCTL = WDTPW + WDTHOLD; ADC10CTL0 = ADC12REF2_5V // reference is VCC (2.5 V)
+ ADC12REFON // turn on reference generator + ADC12SHT02 // sample rate + ADC10ON; // enable ADC
ADC10CTL1 = ADC12SHP; // Use sampling timer ADC12MCTL0 = ADC12EOS // End of sequence (since we are using 1 ADC)
+ ADC12SREF_1 // Define limit between Vref and AVss + ADC12INCH_7; // Read from ADC Channel A7
P6SEL |= BIT7; // Enable A/D channel A7 P1OUT &= BIT1 + BIT0; // P1.0 & P1.1 low (LEDs off) P1SEL &= ~(BIT1 + BIT0); // configure P1.0 & P1.1 for digital IO P1DIR |= 0x03; // P1.0 output for ( i=0; i<0x30; i++); // Delay for reference start-up for (;;) {
ADC12CTL0 |= ADC12ENC + ADC12SC; // enable and start conversion while (ADC10CTL1 & ADC10BUSY); // wait for conversion to complete if (ADC12MEM0 > ...) P1OUT = ...; // display result on LEDs ...
} }
Complete the program such that the on-board LEDs represent graphically the input voltage of the ADC for ���� = 2.5 �,
i.e. no LEDs on for �� < 500 )� and LEDs 1 to 2 on for �� > 2000 )� with linear interpolation in-between. Write the
complete program in the space below:
UC Berkeley, EECS Department
EE40/100 Lab Lab 6: Microcontroller Input/Output Summer 2009
11
1 ��.5
Connect a potentiometer between VCC and GND and connect the middle tap to P6.7. Verify proper circuit operation and
show the result to the GSI.
With this introduction you are in a good position to tackle projects using microcontrollers for all sorts of applications
including electronic thermometers, scales, touch sensor interfaces, light shows, etc.
A final question: with ���� set to 3 V, what value vi corresponds to a reading � = 199? Specify the middle of the range.
�� =
1 ��.6