Thanks to visit codestin.com
Credit goes to www.scribd.com

0% found this document useful (0 votes)
470 views54 pages

Manual Laboratorio Launchpad

This manual show the basic topics about Texas Instruments Microcontroller

Uploaded by

Anthony AC
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOC, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
470 views54 pages

Manual Laboratorio Launchpad

This manual show the basic topics about Texas Instruments Microcontroller

Uploaded by

Anthony AC
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOC, PDF, TXT or read online on Scribd
You are on page 1/ 54

Jonathan W.

Valvano Derived from EE319K Spring 2015 Page 1

Introduction to Embedded Systems


Laboratory Manual
Univ of Texas at Austin
Bard, Erez, Gerstlauer, Janapa Reddi, Telang, Tiwari, Valvano,
Yerraballi

10/2/17 version
Table of Contents
LAB 1. DIGITAL LOGIC IMPLEMENTED ON A MICROCONTROLLER.....................................................................2

LAB 2. FOR-LOOPS, WHILE-LOOPS, IF-THEN BRANCHING, SUBROUTINES, AND TIME DELAYS.................3

LAB 3. SWITCH AND LED INTERFACING.........................................................................................................................6

LAB 4. MINIMALLY INTRUSIVE DEBUGGING METHODS.........................................................................................12

LAB 5. TRAFFIC LIGHT CONTROLLER..........................................................................................................................16

LAB 6. DIGITAL PIANO USING A DIGITAL TO ANALOG CONVERTER...................................................................21

SOLDERING GUIDE...............................................................................................................................................................28

LAB 7C. LCD DEVICE DRIVER FOR THE SITRONIX ST7735......................................................................................30

LAB 8. REAL-TIME POSITION MEASUREMENT SYSTEM..........................................................................................34

LAB 9. DISTRIBUTED DATA ACQUISITION SYSTEM...................................................................................................43

Lab 10. Embedded System Design.............................................................................................................................................52

If you find a mistake, or if you find a section vague or confusing, please email me at
[email protected]

Example projects for Volume 1 (Keil and CCS projects)


http://users.ece.utexas.edu/~valvano/arm/softwaremsp432.html
http://users.ece.utexas.edu/~valvano/arm/downloadmsp432.html

This Lab Manual is associated with the book Embedded Systems: Introduction to the MSP432
Microcontroller, ISBN: 978-1477508992, http://users.ece.utexas.edu/~valvano/arm/msp432.htm

Feel free to download, edit and reuse for educational purposes. Just leave a reference to this site.
Jon Valvano

[email protected] 10/2/2017
Page 2 Embedded Systems: Introduction to the MSP432 Microcontroller

Lab 1. Digital Logic Implemented on a Microcontroller


Preparation
Read Chapters 1 and 2 of the book
Read Sections 3.1, 3.2, 3.3.1-3.3.5, 3.3.9, 3.3.10, 4.1 and 4.2 of the book
Install and run Keil uVision or CCS on your personal computer
Download, unzip, open, compile, and run these five projects (either in lab or on your personal computer)
GPIO_MSP432asm.zip Simple output
Squarewaves_MSP430asm Output to two pins
SSR_MSP432asm Output to one pin
Switch_MSP432asm.zip Simple input from a switch and output to an LED
InputOutput_MSP432asm.zip More complex with inputs and outputs

Purpose
The general purpose of this laboratory is to familiarize you with the software development. You will learn how to
perform digital input/output on parallel ports of the MSP432. Software skills you will learn include port initialization, logic
operations, and unconditional branching.

System Requirements
The specific device you will create is a digital lock with two binary switch inputs and one LED output. The LED
output represents the lock, and the operator will toggle the switches in order to unlock the door. Let P1.0 (Port 1 bit 0) be the
Boolean variable representing the lock (0 means LED is off and door is locked, 1 means LED is on and door is unlocked). Let
P1.1 (Port 1 bit 1 is one input switch) and P1.4 (Port 1 bit 4 is a second switch) be Boolean variables representing the state of
the two switches (1 means the switch is not pressed, and 0 means the switch is pressed). The LED should come on if both
switches are pressed. The P1.0 =1 if and only if P1.1 =0 and P1.4 =0. The specific function you will implement is

P1.0 = (not(P1.1)) and (not(P1.4))

Procedure
The basic approach to this lab will be to develop and debug your system on the LaunchPad.

Part a) Find the five example projects listed above. Compile, download and run all five projects on your LaunchPad and
choose the one that best matches the problem. These four example projects code shows the basic template for the first few
labs. Make a copy of one that projects and rename it Lab 1. Add your names and the most recent date to the comments at the
top of main program file. You will not need global variables in this lab.

Part b) Write a flow chart for this program. We expect 5 to 15 symbols in the flow chart.

Part c) Write pseudo code for this program. We expect 5 to 10 steps in the pseudo code. You may use any syntax you wish,
but the algorithm should be clear.

Part d) You will write assembly code that inputs from P1.1 and P1.4, and outputs to P1.0.

One student should write the flowchart, and the other student should write the pseudo code. Students should work together
for the other parts.

Demonstration
During the demonstration, you will be asked to run your program to verify proper operation. You should be able to
single step your program and explain what your program is doing and why. You need to know how to set and clear
breakpoints. You should know how to visualize Port 1 input/output in the debugger.

Deliverables (Items 1-4 are one pdf file uploaded to Canvas, have this file open during demo.)
1) Flowchart of the system
2) Pseudo code for the algorithm
3) Assembly source code of your final program

10/02/17
Jonathan W. Valvano Derived from EE319K Spring 2015 Page 3

Lab 2. For-loops, while-loops, if-then branching, subroutines, and time delays


Preparation
Read Sections 2.7, 3.3.8 and 4.6 of the book (plus the ones listed in Lab 1)
Make a copy of your Lab1 and rename it Lab2

Purpose
The purpose of this lab is to learn simple programming structures in assembly. You will also learn how to estimate
how long it takes to run software, and use this estimation to create a time delay function. You learn how to use the
oscilloscope to measure time delay. Assembly software skills you will learn include masking, toggling, if-then, subroutines,
and looping.

System Requirements
The system has one input switch and one output LED. Figure 2.1 shows the system as the switch is touched. A
negative logic switch means the P1.4 signal will be 1 (high, 3.3V) if the switch is not pressed, and the P1.4 signal will be 0
(low, +0V) if the switch is pressed. A positive logic red LED interface means if the software outputs a 1 to P1.0 (high, +3.3V)
the LED will turn ON, and if the software outputs a 0 to P1.0 (low, 0V) the red LED will be OFF. In Lab 3, you will attach a
real switch and and real LED to your protoboard, and interface them to your microcontroller. In Lab 2 you first debug on the
real board using the switch and LED on the LaunchPad itself, but no external hardware will be required. Overall functionality
of this system is described in the following rules.
1) Make P1.0 an output and make P1.4 an input (enable pullup for P1.4).
2) The system starts with the LED ON (make P1.0 =1).
3) Delay for about 1 ms
4) If the switch is pressed (PF1.4 is 0), then toggle the LED once, else turn the LED ON.
5) Repeat steps 3 and 4 over and over

P1.4

P1.0

Figure 2.1. The output oscillates when the switch is pressed. The output is high when the switch is released.

Time is very important in embedded systems. One of the simplest ways in which we manage time is determining
how long it takes to run our software. There are two ways to determine how long each instruction takes to execute. The first
method uses the ARM data sheet. For example, the following is a page from the Cortex-M4 Technical Reference Manual.
E.g., see pages 34-38 of http://users.ece.utexas.edu/~valvano/EE345L/Labs/Fall2011/CortexM4_TRM_r0p1.pdf

Figure 2.2. From the Technical Reference Manual page 36.

On the MSP432 the default bus clock is 3 MHz 0.5%. Starting in Lab 4 we will activate the clock system and the bus clock
will be exactly 48 MHz. For now, however, we will run at about 3 MHz. The following is a portion of a listing file with a
simple delay loop. The SUBS and BNE are executed 900 times. The SUBS takes 1 cycle and the BNE takes 1 to 3 (a branch
takes 0 to 3 cycles to refill the pipeline). The minimum time to execute this code is 900*(1+1)/3 s = 600 s. The maximum
time to execute this code is 900*(1+4)/3 s = 1500 s. Since it is impossible to get an accurate time value using the cycle

[email protected] 10/2/2017
Page 4 Embedded Systems: Introduction to the MSP432 Microcontroller

counting method, we will need another way to estimate execution speed. An accurate method to measure time uses a logic
analyzer or oscilloscope. To measure execution time, we cause rising and falling edges on a digital output pin that occur at
know places within the software execution. We can use the logic analyzer or oscilloscope to measure the elapsed time
between the rising and falling edges. In this lab we will measure the time between edges on output P1.0.

0x00000158 F44F7016 MOV R0,#900


0x0000015C 3801 wait SUBS R0,R0,#0x01
0x0000015E D1FD BNE wait
(note: the BNE instruction executes in 3 cycles on the simulator, but in 2 cycles on the real board)

Procedure
The basic approach to Lab 2 will be to develop and debug your system using a negative switch (P1.4) and a positive
logic LED (P1.0) on the MSP432 LaunchPad board. In Lab 3, you will build and test an actual switch and LED.

Part a) Design a subroutine that delays about 1 ms. First, draw a flowchart, and then write pseudocode. You will call the
subroutine with a BL instruction and return with a BX LR instruction. Any delay from 0.8 to 1.2 ms is ok. To implement a
delay, you could set a register to a large number, and then count it down to zero. With a bus clock of 3 MHz, there are 3,000
bus clock cycles in 1 ms. You need to know how long it takes to execute the loop once, then determine the number of times
you need to execute the loop to create the 1 ms delay. E.g., if the time to execute the loop once is 4 cycles, then executing the
loop 3000/4=750 times will be about 1 ms. In this simple estimation we are neglected the other instructions not inside the
loop, because they are 750 times less important.

Part b) Write a main program in assembly that implements the input/output main
system. Pseudo code and flowchart are shown, illustrating the basic steps
for the system. We recommend at this early stage of your design career you Initialize
access the entire I/O port using P1OUT. After you fully understand how I/O ports
works, then you can use bit-banded addressing to access I/O ports.

main Initialize Port 1 LED on


Set the Port 1 direction register so
P1.4 is an input and
P1.0 is an output
Set bit 4 of P1REN to enable the internal register for P1.4 Delay
Specify this resistor as a pull up by setting bit 4 of P1OUT
Set P1.0 so the LED is ON Not pressed Pressed
loop Delay about 1ms Start
Read the switch and test if the switch is pressed
If P1.4=0 (the switch is pressed), LED on LED toggle
toggle P1.0 (flip bit from 0 to 1, or from 1 to 0)
If P1.4=1 (the switch is not pressed),
set P1.0, so LED is ON
Go to loop

Part c) Use a logic analyzer or oscilloscope to measure the delay function.

Part d) Load your software onto the board and test it. If the P1.4 switch is not pressed, then the red LED is on, which you
can see by noticing its bright color. If the P1.4 switch is pressed, then the red LED toggles 500 times a second, which you can
see by noticing its dim red color. Use a dual channel scope or logic analyzer to capture data like Digure 2.1.

Demonstration (both partners must be present, and demonstration grades for partners may be different)
You will show the TA your program operation on the real board. Be prepared to explain how the delay function
works. How would it be different if it were 100 ms instead of 1 ms? The TA will pick an instruction from your code and ask
you which addressing mode it uses. Execute the program step-by-step and run to cursor. What is a Reset Vector and why do
you need it? What does AREA do? What does EXPORT do?

10/02/17
Jonathan W. Valvano Derived from EE319K Spring 2015 Page 5

Deliverables
1) Two photographs, like Figure 2.1, showing the input and the output. One showing the touch and release, and the
other showing a close up of the toggling showing the 1ms delay between edges on P1.0
2) Flowchart of the delay function
3) Pseudocode of the delay function
4) Assembly source code of your final program

[email protected] 10/2/2017
Page 6 Embedded Systems: Introduction to the MSP432 Microcontroller

Lab 3. Switch and LED interfacing


Preparation
Read Sections 2.7, 3.3.8, and 4.2
Make a copy of your Lab2 and rename it Lab3
Download and install either EagleCAD or PCBartist

Purpose
Lab 3 is the continuation of Lab 2; essentially, you will implement in external hardware what you developed in Lab
2. The purpose of this lab is to learn how to interface a switch and an LED. You will perform explicit measurements on the
circuits in order to verify they are operational and to improve your understanding of how they work.
You will learn to use a free design tool called PCBArtist from Advanced Circuits for drawing electrical circuits. To
download this tool, go to http://www.4pcb.com/ When downloading this free application from the internet, be careful NOT to
accept any of the special offers (when asked yes or no, say NO.) When installed, there will be a drawing application called
PCB Artist, which we will use to draw electrical circuits. We will also use PCB Artist or EagleCAD to design PCB boards in
Volume 2.
To install EagleCAD, go to http://www.cadsoftusa.com/ and follow the directions. You can use the free version for
the labs in this course.

System Requirements
Figure 4.13 in the book shows a switch interface that implements positive logic. In this lab you will connect it to
P4.0. The right side of Figure 4.14 shows an LED interface that implements positive logic. You will attach this switch and
LED to your protoboard (the white piece with all the holes), and interface them to your MSP432. Overall functionality of this
system is the similar to Lab 2, with five changes: 1) the pin to which we connect the switch is moved to P4.0, 2) you will
have to remove the REN initialization because pull up is no longer needed. 3) the pin to which we connect the LED is moved
to P5.0, 4) the switch is changed from negative to positive logic, and 5) you should increase the delay so it flashes about 8
Hz.
1) Make P4.0 an output and make P5.0 an input.
2) The system starts with the LED on (make P5.0 =1).
3) Wait about 62 ms
4) If the switch is pressed (P4.0 is 1), then toggle the LED once, else turn the LED on.
5) Steps 3 and 4 are repeated over and over

Procedure
Back in Lab 2, you developed and debugged your system using a built-in switch and LED to run on the real board.
During this lab you will build and test your hardware. The final demonstration will be run stand-alone without connection to
the PC. This stand-alone operation illustrates how embedded systems operate.

Part a) Using PCBartist or EagleCAD draw the interface for the switch and the LED. When you are done, print the circuit as
a pdf file, and email this pdf file to your TA for approval. The first step is to place an LED, a switch and resistors onto the
page, moving them close to each other as needed. The second step is to add traces (these will be actual wires when you build
it). In general, we draw circuit diagrams so current flows from top to bottom on the page.

Figure 3.1. PCB Artist drawing one possible Lab 3 drawing. R19 controls the LED current.

10/02/17
Jonathan W. Valvano Derived from EE319K Spring 2015 Page 7

In the left side of Figure 3.2, wire1 and wire2 cross in the circuit diagram, but are not electrically connected, because there is
NO dot at the point of crossing. In the right side of Figure 3.2, wire1 and wire2 cross in the circuit diagram, and are
electrically connected, because there IS a dot at the point of crossing.

Figure 3.2. When traces cross without a dot they are not connected. When traces cross with a dot they are connected.

Part b) Make the five changes listed in the requirements section to your Lab 2 system. The best approach to time delay will
be to use a hardware timer, which we will learn in Lab 4. In this lab, however, we do not expect you to use the hardware
timer. Again, use the logic analyzer or scope to verify the software operates properly. In this lab the delay was increased so
you will be able to see the LED flash with your eyes.

Part c) Engineers must be able to read datasheets during the design, implementation and debugging phases of their projects.
During the design phase, datasheets allow us to evaluate alternatives, selecting devices that balance cost, package size, power,
and performance. For example, we could have used other IC chips like the 7405, 74LS05, or 74HC05 to interface the LED to
the MSP432. In particular, we chose the 7406 or 74LS06 because it has a large output current ( IOL = 40 mA), 6 drivers, and is
very inexpensive (59). During the implementation phase, the datasheet helps us identify which pins are which. During the
debugging phase, the datasheet specifies input/output parameters that we can test. Download the 7406 and LED datasheets
from the web
http://users.ece.utexas.edu/~valvano/Datasheets/7406.pdf
http://users.ece.utexas.edu/~valvano/Datasheets/LED_red.pdf
and find in the datasheet for the 7406 the two pictures as shown in Figure 3.3. Next, hold your actual 7406 chip and identify
the location of pin 1. Find in the datasheet the specification that says the output low voltage ( VOL) will be 0.4V when the
output low current (IOL) is 16 mA (this is close to the operating point we will be using for the LED interface).

Figure 3.3. Connection diagram and physical package diagram for the 7406.

Using the data sheet, hold an LED and identify which pin is the anode and which is the cathode. Sometimes we are asked to
interface a device without a data sheet. Notice the switch has 4 pins in a rectangular shape, as shown in Figure 3.6. Each
button is a single-pole single-throw normally-open switch. All four pins are connected to the switch. Using your ohmmeter

[email protected] 10/2/2017
Page 8 Embedded Systems: Introduction to the MSP432 Microcontroller

determine which pairs of pins are internally connected, and across which pair of pins is the switch itself. In particular, draw
the internal connections of the switch, started in Figure 3.4, showing how the four pins are connected to the switch.

Figure 3.4. Connection diagram for the normally open switch.

To build circuits, well use a solderless breadboard, also referred to as a protoboard. The holes in the protoboard are
internally connected in a systematic manner, as shown in Figure 3.5. The long rows of of 50 holes along the outer sides of the
protoboard are electrically connected. Some protoboards like the one in Figure 3.7 have four long rows (two on each side),
while others have just two long rows (one on each side). We refer to the long rows as power buses. If your protoboard has
only two long rows (one on each side, we will connect one row to +3.3V and another row to ground. If your protoboard has
two long rows on each side, then two rows will be ground, one row will be +3.3V and the last row will be +5V. Use a black
marker and label the voltage on each row. In the middle of the protoboard, youll find two groups of holes placed in a 0.1
inch grid. Each adjacent row of five pins is electrically connected. We usually insert components into these holes. IC chips
are placed on the protoboard, such that the two rows of pins straddle the center valley. To make connections to the MSP432
we can run male-male solid wire from the bottom of the microcontroller board to the protoboard. For example, assume we
wish to connect MSP432 P5.0 output to the 7406 input pin 1. First, cut a 24 gauge solid wire long enough to reach from P5.0
and pin 1 of the 7406. Next, strip about 0.25 inch off each end. Place one end of the wire in the hole for the P5.0 and the other
end in one of the four remaining of the 7406 pin 1.

Figure 3.5. All the pins on each of the four long rows are connected. The 5 pins in each short column are connected. Use
male-male wires to connect signals on the LaunchPad to devices on the protoboard. Make sure ground wire connected
between the LaunchPad and your circuit. The +3.3V and +5V power can be wired from the LaunchPad to your circuit. I like
to connect the two dark blue rows to ground, one red row to +3.3V and the other red row to +5V.

10/02/17
Jonathan W. Valvano Derived from EE319K Spring 2015 Page 9

If you are unsure about the wiring, please show it to your TA before plugging in the USB cable. I like to place my
voltmeter on the +3.3V power when I first power up a new circuit. If the +3.3V line doesnt immediately jump to +3.3V, I
quickly disconnect the USB cable.

Part d) Before you run the entire system you will test component individually on the real board. Please get your design
checked by the TA before you apply power (plug in the USB cable). Do not place or remove wires on the protoboard while
the power is on.

Before connecting the switch to the microcomputer, please take the measurements in Table 3.1 using your digital multimeter.
The input voltage (VP4.0) is the signal that will eventually be connected to P4.0. With a positive logic switch interface, the
resistor current will be VP4.0/10k. The voltages should be near +3.3 V or near 0 V and the currents will be less than 1 mA.
The goal is to verify the VP4.0 voltage is low when the switch is not pressed and high when the switch is pressed.
The circuit in Figure 3.1 used R1 as the 10k resistor. There are other 10k resistors in the PCB artist starter file; any one of
which could have been used.

Parameter Value Units Conditions


Resistance of the with power off and
10k resistor, R1 ohms disconnected from circuit
(measured with ohmmeter)

Supply Voltage, V+3.3 volts Powered


(measured with voltmeter)
Powered, but
Input Voltage, VP4.0 volts with switch not pressed
(measured with voltmeter)
Powered, but switch not pressed
Resistor current mA I=VPE0/R1 (calculated and
measured with an ammeter)
Powered and
Input Voltage, VP4.0 volts with switch pressed
(measured with voltmeter)
Powered and switch pressed
Resistor current mA I=VP4.0/R1 (calculated and
measured with an ammeter)
Table 3.1. Switch measurements.

Next, you can connect the input voltage to P4.0 and use the debugger to observe the input pin to verify the proper operation
of the switch interface. You will have to single step through the code that initializes Port 4, and P4.0. As you single step you
should see the actual input as controlled by the switch you have interfaced, see Figure 3.1.

The next step is to build the LED output circuit. LEDs emit light when an electric current passes through them, as
shown in Figure 3.6. LEDs have polarity, meaning current must pass from anode to cathode to activate. The anode is labeled
a or + , and cathode is labeled k or -. The cathode is the short lead and there may be a slight flat spot on the body of round
LEDs. Thus, the anode is the longer lead. LEDs are not usually damaged by heat when soldering. Furthermore, LEDs will
not be damaged if you plug it in backwards. LEDs however wont work plugged in backwards of course. Look up the pin
assignments in the 7406 data sheet. Be sure to connect +5V power to pin 14 and ground to pin 7. The 0.1 F capacitor from
+5V to ground filters the power line. Every digital chip (e.g., 7406) should have a filter capacitor from its power line (i.e., pin
14 VCC) to ground. The capacitor in your kit is ceramic, which is not polarized, meaning it can be connected in either
direction.

Anode a + k -

Photo: Cathode Circuit symbol: anode cathode


Figure 3.6. LEDs.

[email protected] 10/2/2017
Page 10 Embedded Systems: Introduction to the MSP432 Microcontroller

The circuit in Figures 3.1 used R19 as the 220 resistor. You should work through the design equations as described in the
book for your particular LED

Take the measurements as described in Table 3.2. The R19 measurement occurs before R19 is inserted into the circuit.
Single step your software to make PE1 to output. Initially PE1 will be low. So take four measurements with PE1 low, rows
2,3,4,5 in Table 3.2. Then, single step some more until PE1 is high and measure the three voltages (rows 8,9,10 in Table 3.2).
When active, the LED voltage should be about 2 V, and the LED current should be about 10 mA. The remaining rows are
calculated values, based on these 8 measurements. The LED current (row 12) can be determined by calculation or by direct
measurement using the ammeter function. You should perform both ways to get LED current.

Part e) Debug your combined hardware/software system on the actual MSP432 board.

Warning: NEVER INSERT/REMOVE WIRES/CHIPS WHEN THE POWER IS ON.

Row Parameter Value Units Conditions


Resistance of the with power off and
1 220 resistor, R19 ohms disconnected from circuit
(measured with ohmmeter)
+5 V power supply (measured with voltmeter,
2 V+5 volts notice that the +5V power is
not exactly +5 volts)
MSP432 Output, VP5.0
3 input to 7406 volts with P5.0 = 0
(measured with voltmeter)
7406 Output, Vk-
4 LED k- volts with P5.0 = 0
(measured with voltmeter)
LED a+, Va+
5 Bottom side of R19 volts with P5.0 = 0
(measured with voltmeter)

6 LED voltage volts calculated as Va+ - Vk-

calculated as (V+5 - Va+)/R19


7 LED current mA and
measured with an ammeter
MSP432 Output, VP5.0`
8 input to 7406 volts with P5.0 = 1
(measured with voltmeter)
7406 Output, Vk-
9 LED k- volts with P5.0 = 1
(measured with voltmeter)
LED a+, Va+
10 Bottom side of R19 volts with P5.0 = 1
(measured with voltmeter)

11 LED voltage volts calculated as Va+ - Vk-

calculated as (V+5 - Va+)/R19


12 LED current mA and
measured with an ammeter
Table 3.2. LED measurements (assuming the 220 resistor is labeled R19).

10/02/17
Jonathan W. Valvano Derived from EE319K Spring 2015 Page 11

Demonstration (both partners must be present, and demonstration grades for partners may be different)
You will show the TA your program operation on the actual MSP432 board. The TA may look at your data and
expect you to understand how the data was collected and how the switch and LEDs work. Also be prepared to explain how
your software works and to discuss other ways the problem could have been solved. Why the 7406 was used to interface the
LED? I.e., why did we not connect the LED directly to the MSP432. Why do you think you need the capacitor for 7406 chip?
Why was the delay increased from 1 to 62 ms? How would you modify the software to change the rate at which LED
flickers? What operating point (voltage, current) exists when the LED is on? Sketch the approximate current versus voltage
curve of the LED. Explain how you use the resistor value to select the operating point. What is the difference between a
positive logic and negative logic interface for the switch or the LED? We may test to see if you can measure voltage, current
and/or resistance with your meter (so bring your meter to the demonstration).

Deliverables (Items 1, 2, 3, 4, 5 are one pdf file uploaded to Canvas, have this file open during demo.)
1) Circuit diagram, using PCBArtist, or EagleCAD
2) Screenshot like Figure 3.7 showing your debugging on the dual channel scope
3) Switch measurements (Table 3.1)
4) LED measurements (Table 3.2)
5) Assembly source code of your final program

Precautions to avoid damaging your system


0) Do not attach or remove wires on the protoboard when power is on. Always shut power off when making hardware
changes to the system.
1) Touch a grounded object before handling CMOS electronics. Try not to touch any exposed wires.
2) Do not plug or unplug the modules into the LaunchPad while the system is powered.
3) Do not use the MSP432 with any external power sources, other than the USB cable. In particular, avoid connecting signals
to the MSP432 that are not within the 0 to +3.3V range. In particular, voltages less than 0V or greater than +3.3V will
damage the microcontroller.
6) See Figure 4.3 in the textbook to see which pins have circuits already connected.

Figure 3.7. Testing of Lab 3, showing P4.0 high, and the P5.0 output toggling at 8 Hz.

[email protected] 10/2/2017
Page 12 Embedded Systems: Introduction to the MSP432 Microcontroller

Lab 4. Minimally Intrusive Debugging Methods


Preparation
Read Sections 4.3, 4.4, 5.1, 5.2, 5.5, 5.7, 6.1, 6.2, and 6.9
Make a copy of your Lab3 and rename it Lab4
Download, open, compile, and run the project
SysTick_MSP432asm SysTick functions
ClockSystem_MSP432asm Uses the crystal to run at 48 MHz
These videos https://www.youtube.com/playlist?list=PLyg2vmIzGxXHYEHQrxNxGcRg6vCTB20Ud relate to Lab 4.
Purpose
The purpose of this lab is to learn minimally intrusive debugging skills. When visualizing software running in real-
time on an actual microcomputer, it is important use minimally intrusive debugging tools. The first objective of this lab is to
develop an instrument called a dump, which does not depend on the availability of a debugger. A dump allows you to capture
strategic information that will be viewed at a later time. Many programmers use the printf statement to display useful
information as the programming is being executed. On an embedded system we do not have the time or facilites to use printf.
Fortunately, we can use a dump in most debugging situations for which a printf is desired. The second useful debugging
technique you will learn is called a heartbeat. A heartbeat is a visual means to see that your software is still running. The
debugging techniques in this lab use both hardware and software and are appropriate for the real MSP432. Software skills
you will learn include indexed addressing, array data structures, the high speed clock, the SysTick timer, and subroutines.

System Requirements
In this lab, you will design, implement, test and employ software debugging instruments to experimentally verify the correct
operation of your Lab 3 system. For the software approach, you will record the P4.0 and P5.0 (both the input and output
signals) and the time during each execution through the outer loop of the main program of Lab 3 as your system runs in real
time. You will activate the 48 MHz (by calling the Clock_Init48MHz function, which in turn will execute Program 4.6c
of the book) to make the microcontroller run at 48 MHz. You will also activate the SysTick timer (call SysTick_Init
shown in Program 4.7 of the book), which will make the 24-bit counter decrement every bus cycle 1000/48 = 20.833ns. We
will use this counter (SYSTICK_STCVR) to measure time differences up to 349.5 ms. To measure the current time, you
simply read the 24-bit SYSTICK_STCVR value. This software dump should store P4.0 and P5.0 and SYSTICK_STCVR
data into arrays while the system is running in real-time, and the information will be viewed at a later time. Software dumps
are an effective technique when debugging real-time software on an actual microcomputer. We will define the debugging
instrument as minimally intrusive if the time to collect and store the information is short compared to the time between
when information is collected. You will define an array capable of storing about 3 seconds worth of Port E measurements,
and an array capable of storing about 3 seconds worth of time measurements. For example, if the outer loop of your Lab 3
executes in about 62 ms, then the loop will be executed about 50 times in 3 seconds (3000/62), so the array sizes will need to
be 50 elements each. You may use either pointers or counters to store data in the arrays. You will collect performance data on
the system with a no-touch, touch, no-touch sequence during the 3-second measurement.

P1.0 is already interfaced to an LED on the MSP432 board itself. Write debugging software and add it to the Lab 3
system so that this LED always flashes while your program is running. In particular, initialize the direction register so P1.0 is
an output, and add code that toggles the LED each time through the loop. A heartbeat of this type will be added to all
software written for Labs 4, 6, 7, 8, and 9 in this class. Lab 5 will use P1.0 as part of the system output. It is a quick and
convenient way to see if your program is still running. When your system gets more complex, you can implement multiple
heartbeats at various strategic places in the software and that toggle much faster than the eye can see. In these situations, you
will use a logic analyzer to visualize many high-speed digital signals all at once. However, in this class there will be one
heartbeat on P1.0, and the heartbeat must occur slow enough to be seen with the eye.

Procedure
The basic approach is to design and test individual components, and then put the system together and test in on the
real MSP432.

Part a) When your main program calls Clock_Init48MHz, this subroutine will activate the high speed crystal making bus
clock 48 MHz. Adjust the delay function so it delays 62 ms. Write two debugging subroutines that implement a dump
instrument. If we saved just the input/output data, then the dump would be called functional debugging, because we would
capture input/output data of the system, without information specifying when the input/output was collected. However, you

10/02/17
Jonathan W. Valvano Derived from EE319K Spring 2015 Page 13

will save both the input/output data and the time, so the dump would be classified as performance debugging. The first
subroutine (Debug_Init) initializes your dump instrument. The initialization should activate the SysTick timer, place
0xFFFFFFFF into the two arrays, and initialize pointers and/or counters as needed. The second subroutine
(Debug_Capture) that saves one data-point (P4.0 input data, and P5.0 output data) in the first array and the
SYSTICK_STCVR in the second array. Since there are only two bits to save in the first array, pack the information into one
value for ease of visualization when displayed in hexadecimal. Put the P4.0 value into bit 4 and the P5.0 value into bit 0. I.e.,
Input (P4.0) Output (P5.1) save data
0 0 0000,00002, or 0x00000000
0 1 0000,00012, or 0x00000001
1 0 0001,00002, or 0x00000010
1 1 0001,00012, or 0x00000011

In this way, you will be able to visualize the data in an effective manner. Place a call to Debug_Init at the beginning of the
system, and a call to Debug_Capture at the start of each execution of the outer loop. The basic steps involved in designing
the data structures for this debugging instrument are as follows
Allocate DataBuffer in RAM (to store 3 seconds of input/output data)
Allocate TimeBuffer in RAM (to store 3 seconds of timer data)
Allocate two pointers (DataPt, TimePt), one for each array, pointing to the place to save the next data

The basic steps involved in designing Debug_Init are as follows


Set all entries of the first buffer to 0xFFFFFFFF (meaning no data yet saved)
Set all entries of the second buffer to 0xFFFFFFFF (meaning no data yet saved)
Initialize the two pointers to the beginning of each buffer
Activate the SysTick timer (call SysTick_Init shown in Program 4.7 of the book)

The basic steps involved in designing Debug_Capture are as follows


Save any registers needed
Return immediately if the buffers are full (pointer past the end of the buffer)
Read P4.0 and P5.0 and the SysTick timer (SYSTICK_STCVR)
Mask capturing just P4.0 and P5.0
Shift P4.0 into bit 4 position, and P5.0 into bit 0 position
Dump this port information into DataBuffer using the pointer DataPt
Increment DataPt to next address
Dump time into TimeBuffer using the pointer TimePt
Increment TimePt to next address
Restore any registered saved and return
For regular functions we are free to use R0, R1, R2, R3, and R12 without preserving them. However, for debugging
instruments, we should preserve all registers, so that the original program is not affected by the execution of the debugging
instruments. The temporary variables may be implemented in registers. However, the buffers and the pointers should be
permanently allocated in global RAM. You can observe the debugging arrays using a Memory window. Look in the map file
to find the addresses of the buffers. After you have debugged your code in simulation mode, capture a screenshot showing the
results as the switch is pressed then not pressed. The dumped data should start with some 0x01 data, next it should oscillate
between 0x10, 0x11 as the switch is pressed, then return to 0x01 when the switch is released.

Part b) One simple way to estimate the execution speed is to assume each instruction requires about 2 cycles. By counting
instructions and multiplying by two, you can estimate the number of cycles required to execute your Debug_Capture
subroutine. Assuming the 20.833ns bus cycle time, convert the number of cycles to time. Next, estimate the time between
calls to Debug_Capture. Calculate the percentage overhead required to run the debugging instrument (100 times
execution time divided by time between calls, in percent). This percentage will be a quantitative measure of the intrusiveness
of your debugging instrument. Type the estimations and calculations in as comments to your program.

Part c) Write the debugging instruments that implement the heartbeat (initialization and toggle). The heartbeat instruments
can be embedded as simple assembly language software without making them separate subroutines.

[email protected] 10/2/2017
Page 14 Embedded Systems: Introduction to the MSP432 Microcontroller

Part d) Debug each component first, and then connect the components into a system and test it on the actual board.
Figure 4.2 is screenshot logic analyzer output of Lab 4.

Figure 4.2. Simulation output showing the input, output and heartbeat.

Lets look at one measurement 0x00ABE5DA-0x0057CDB4 = 11265498-5754292=5511206. Since each cycle is 20.8ns,
5511206*20.8ns = 115ms. For this solution, the measurement agrees with the data collected by an oscilloscope and shown in
Figure 4.4.

Figure 4.3. Debugging dump of data is observed in the memory window.

Part e) The input is on P4.0 and the output is on P5.0. P1.0 is a heartbeat. Run your debugging instrument capturing the
sequence of P4.0 inputs and P5.0 outputs as you touch, then release the switch. Use the collected data to measure the period
of the flashing LED. Your measurement should be accurate to 20.833 ns.

Demonstration (both partners must be present, and demonstration grades for partners may be different)
You will show the TA your program operation on the actual board. You should be able to connect P1.0 to an oscilloscope to
verify the main loop is running at about every 62 ms. The TA may look at your data and expect you to understand how the
data was collected and what the data means. Also be prepared to explain how your software works and to discuss other ways
the problem could have been solved. Why did you have to change the delay function after the clock system was activated?
How did you change it? Why? The TA will pick an instruction in your program and ask how much time does it take that
instruction to execute in sec. Does it always take same amount of time to execute? You will be asked to create a breakpoint,
and add the port pin to the oscilloscope. Is Debug_Capture minimally intrusive or non-intrusive? What do you mean by
intrusiveness? Is your code friendly? How do you define masking? How do you set/clear one bit in without affecting other
bits? What is the difference between the B, BL and BX instructions? How do you initialize the SysTick? You should
understand every step of the function SysTick_Init. How do you change the rate at which SysTick counts? Describe
three ways to measure the time for a software function to execute? How do you calculate the sizes of the port data and the
timestamp data? If you used 32-bit data for DataBuffer what would be the advantages of 8-bit data? If you used 8-bit data
for DataBuffer what would be the advantages of 32-bit? Could you have stored the time-stamp data in 8-bit, 16-bit, or 24-
bit arrays? Why does the pointer to the time-stamp array need to be incremented by four, if you want to point to the next
element in the array? How do you allocate global variables?

10/02/17
Jonathan W. Valvano Derived from EE319K Spring 2015 Page 15

Deliverables
1) A figure showing signals on a dual channel scope or a three channel logic analyzer while the system running like
Figure 4.4.
2) Assembly listing of your final program with both the dump and heartbeat instruments
3) Estimation of the execution time of your debugging instrument Debug_Capture (part b)
4) Results of the debugging instrument (part e) and the calculation of the flashing LED period in msec.

Figure 4.4. The input and output signals are measured with a two channel oscilloscope. When the switch is pressed, P4.0
goes high. When the software sees P4.0 high it toggles P5.0 every 62ms. In this solution with system actually toggled P5.0
every 69 ms.

[email protected] 10/2/2017
Page 16 Embedded Systems: Introduction to the MSP432 Microcontroller

Lab 5. Traffic Light Controller


Preparation
Read Sections 4.4, 6.1, 6.4, 6.5 in the textbook
See http://users.ece.utexas.edu/~valvano/Datasheets/LED_yellow.pdf
See http://users.ece.utexas.edu/~valvano/Datasheets/LED_green.pdf
Download, unzip, build and run the FSM examples
PointerTrafficLight_MSP432 and MealyEngineControl_MSP432.
https://www.youtube.com/playlist?list=PLyg2vmIzGxXEle4_R2VA_J5uwTWktdWTu
Purpose
This lab has these major objectives: 1) the understanding and implementing linked data structures; 2) learning how
to create a segmented software system; and 3) the study of real-time synchronization by designing a finite state machine
controller. Software skills you will learn include advanced indexed addressing, linked data structures, creating fixed-time
delays using the SysTick timer, and debugging real-time systems.

System Requirements
All software in this lab must be developed in C. Projects in C are a little different than the assembly projects used for
Labs 1 to 4. The project configuration and the startup.s file are different.
Consider a 4-corner intersection as shown in Figure 5.1. There are two one-way streets are labeled South (cars travel
South) and West (cars travel West). There are three inputs to your MSP432, two are car sensors, and one is a walk button. The
South sensor will be true (1) if one or more cars are near the intersection on the South road. Similarly, the West sensor will be
true (1) if one or more cars are near the intersection on the West road. The Walk button will be pushed by a pedestrian when
he or she wishes to cross in any direction. To request a walk, a pedestrian must push and hold the walk button for at least 2
seconds, after which person can release the button, and the walk request will be remembered. In contrast, when a car sensor is
released, it means no cars are waiting to enter the intersection. You will use 8 outputs from your microcomputer that control
the traffic lights, the walk light, and the dont walk light. The walk light will be the green LED (P2.1) on the
LaunchPad and the dont walk light is the red LED (P2.0) on the LaunchPad. When the walk condition is signified,
pedestrians are allowed to cross. When the dont walk condition flashes (and the two traffic signals are red), pedestrians
should hurry up and finish crossing in any direction. When the dont walk condition is on steady, pedestrians should not
enter the intersection. The red and green LED connected to P2.0 and P2.1 respectively must be used. All other inputs and
outputs must be built on the protoboard.

Walk
South

R
Y West
G
Walk
R Y G GR
Dont walk
PF3
PF1

Figure 5.1. Traffic Light Intersection (three inputs and eight outputs).

Traffic should not be allowed to crash. I.e., there should not be only a green or only a yellow LED on one road at the
same time there is only a green or only a yellow LED on the other road. You should exercise common sense when assigning
the length of time that the traffic light will spend in each state; so that the system changes at a speed convenient for the TA
(stuff changes fast enough so the TA doesnt get bored, but not so fast that the TA cant see what is happening). Cars should
not be allowed to hit the pedestrians. The walk sequence should be realistic, showing three separate conditions: 1) walk, 2)
hurry up using a flashing LED, and 3) dont walk. You may assume the two car sensors remain active for as long as
service is required. However a request for walk is signified by a push and release, where the walk button is pushed for at least
2 seconds.

10/02/17
Jonathan W. Valvano Derived from EE319K Spring 2015 Page 17

There is no single, best way to implement your system. However, your scheme must use a linked data structure
stored in ROM. There should be a 1-1 mapping from the FSM states and the linked elements. A good solution will have
about 15 to 30 states in the finite state machine, and provides for input dependence. Try not to focus on the civil engineering
issues. I.e., the machine does not have to maximize traffic flow or minimize waiting. On the other hand if there are multiple
requests, the system should cycle through, servicing them all. Build a quality computer engineering solution that is easy to
understand and easy to change. We expect your solution to behave reasonably and have 15 to 30 states. It is unacceptable if
your machine is less than 15 states. If your machine has more than 30 states you have made it more complicated than we had
in mind. Because we have three inputs, there will be 8 next state arrows. One way to draw the FSM graph to make it easier to
read is to use X to signify dont care. For example, compare the Figure 6.9 in the book to the FSM graph in Figure 5.2 below.
Drawing two arrows labeled 01 and 11 is the same as drawing one arrow with the label X1. When we implement the data
structure, we will expand the shorthand and explicitly list all possible next states.
Next if input is 01 or 11
0X
X0 X1 XX 1X Output
goN waitN goE waitE
100001 100010 001100 010100
30 5 30 5
XX
Wait time
Figure 5.2. FSM from the book Figure 6.20 redrawn with a short hand format.

This lab was written in a manner intended to give you a great deal of flexibility in how you draw the FSM graph,
while at the same time require very specific boundaries on how the FSM controller must be written. This flexibility causes
students to be question when am I done? or is this enough for an A? To clarify the distinction between computer
engineering, and civil engineering, I restate the computer engineering requirements. In particular do these 9 requirements
well and you can get a good grade on this lab.

0) The system provides for input dependence. This means each state has 8 arrows such that the next state
depends on the current state and the input. This means you can not solve the problem by simply cycling
through all the states regardless of the input. You should not implement a Mealy machine.

1) There must be a 1-1 mapping between state graph and data structure. For a Moore machine, this means
each state in the graph has a name, an output, a time to wait, and 8 next state arrows (one for each input).
The data structure has exactly these components: a name, an output, a time to wait, and 8 next state
pointers (one for each input). There is no more or no less information in the data structure then the
information in the state graph.

2) There can be no conditional branches (do-while, while-loop, if-then, or for-loops) in your system, other
than in SysTick_Wait and in SysTick_Wait10ms. See the Example 6.5 in the book. You will have
an unconditional while-loop in the main program that runs the FSM controller.

3) The state graph defines exactly what the system does in a clear and unambiguous fashion.

4) Each state has the same format of each state. This means every state has exact one name, one 8-bit output,
one time to wait, and 8 next pointers.

5) Please use good names and labels (easy to understand and easy to change). Examples of bad state names
are S0 and S1.

6) Do not allow cars to crash into each other. Do not allow pedestrians to walk in one direction while any
cars are allowed to go. Engineers do not want people to get hurt.

7) There should be 10 to 30 states with either a Moore finite state machine. What if I have less than 10
states? Usually students with less than 10 states did not flash the dont walk light, or they flashed the

[email protected] 10/2/2017
Page 18 Embedded Systems: Introduction to the MSP432 Microcontroller

lights using a counter. Counters and variables violate the no conditional branch requirement. If you are
less than 10 to 15 states, you probably did not handle the 2 second walk button recognition.

8) If the pedestrian pushes the walk button for 2 or more seconds, eventually a walk light must occur. If the
pedestrian pushed the walk button for less than 2 seconds, it is ok for the system to generate a walk signal
or to not generate a walk signal.

One way to handle the 2-second walk button requirement is to add a duplicate set of states. The first set of states
means the walk button is not pressed. The second set of states means the walk operation is requested. Go from the first set to
the second set whenever the walk is pushed. Go from the second back to the first whenever the walk condition is output. The
two sets of states allow you to remember that a walk has been requested; in this way the request is serviced when appropriate.
There are many civil engineering questions that students ask. How you choose to answer these questions will
determine how good a civil engineer you are, but will not affect your grade on this lab. For each question, there are many
possible answers, and you are free to choose how you want to answer it. It is reasonable however for the TA to ask how you
would have implemented other answers to these civil engineering questions using the same FSM structure.

0) How long should I wait in each state? Possible answer: 1 to 2 seconds of real TA time.

1) What happens if I push 2 or 3 buttons at a time? Possible answer: cycle through the requests servicing
them in a round robin fashion.

2) What if I push the walk button, but release it before 2 seconds are up? Possible answer: ignore the
request as if it never happened. Possible answer: service it or ignore it depending on exactly when it
occurred.

3) What if I push a car button, but release it before it is serviced? Possible answer: ignore the request as if it
never happened (e.g., car came to a red light, came to a full stop, and then made a legal turn). Possible
answer: service the request or ignore it depending on when it occurred.

4) Assume there are no cars and the light is green on the North, what if a car now comes on the East? Do I
have to recognize a new input right away or wait until the end of the wait time? Possible answer: no, just
wait until the end of the current wait, then service it. Possible answer: yes; break states with long waits
into multiple states with same output but shorter waits.

5) What if the walk button is pushed while the dont walk light is flashing? Possible answer: ignore it, go to
a green light state and if the walk button is still pushed, then go to walk state again. Possible answer: if
no cars are waiting, go back to the walk state. Possible answer: remember that the button was pushed,
and go to a walk state after the next green light state.

6) Does the walk occur on just one street or both? Possible answer: stop all cars and let people walk across
either or both streets.

7) How do I signify a walk condition? Answer: You must use the on board green LED for walk, and on
board red LED as the dont walk.

10/02/17
Jonathan W. Valvano Derived from EE319K Spring 2015 Page 19

Figure 5.3. Massachusetts walk signified by red and yellow (phased out in 2011).

Procedure
The C compiler will create a segmented software system putting global variables into RAM, and local variables into
registers or on the stack. The compiler will place constants, and fixed data structures, and program object code into
EEPROM. Most microcontrollers have a rich set of timer functions. For this lab, you will the SysTick timer to wait a
prescribed amount of time. You may use the functions in Section 4.4, but you are responsible for understanding all the details
of Program 4.7. On the other hand you may use the Program 4.6 to activate the 48 MHz crystal. You are not responsible for
the details of how the clock system works, but are responsible for understanding the tradeoff between software execution
speed and electrical power.
In general, using cycle-counting (for-loops) for delays has the problem of conditional branches and data-dependent
execution times. If an interrupt were to occur during a cycle-counting delay, then the delay would be inaccurate using the
cycle-counting method. In the above method, however, the timing will be very accurate, even if an interrupt were to occur
while the microcomputer was waiting. In more sophisticated systems, using timer interrupts provide a more flexible and even
more accurate mechanism for microcomputer synchronization. Interrupt synchronization will be used in Labs 6 through 10. A
linked solution may not run the fastest, or occupy the fewest memory bytes, but it is a structured technique that is easy to
understand, easy to implement, easy to debug, and easy to upgrade.
The basic approach to this lab will be to first develop and debug each component separately. After each component is
debugged, you will combine them into one system, and test it on the real MSP432. Because we do not want to wait the
minutes required for an actual intersection, the cars in this traffic intersection travel much faster than real cars. In other
words, you are encouraged to adjust the time delays so that the operation of your machine is convenient for you to debug and
for the TA to observe during demonstration.

Part a) Decide which port pins you will use for the inputs and outputs. Avoid the pins with hardware already connected.
Figure 4.3 in the book shows the pins to avoid. \

Part b) Design a finite state machine that implements a good traffic light system. Include a graphical picture of your finite
state machine showing the various states, inputs, outputs, wait times and transitions.

Part c) Draw your hardware circuit diagram using the program like PCB Artist or EagleCAD. The first step is to interface
three push button switches for the sensors. You should implement positive logic switches. Do not place or remove wires on
the protoboard while the power is on. Build the switch circuits and test the voltages using a digital voltmeter. You can also
use the debugger to observe the input pin to verify the proper operation of the interface.
The next step is to build six LED output circuits. Build the system physically in a shape that matches a traffic
intersection, so the TA can better visualize the operation of the system. Look up the pin assignments in the 7406 data sheet.
Be sure to connect +5V power to pin 14 and ground to pin 7. Write a simple main program to test the LED interface. Set the
outputs high and low, and measure the three voltages (input to 7406, output from 7406 which is the LED cathode voltage, and
the LED anode voltage).

Part d) Write and debug the C code that implements the traffic light control system. Capture logic analyzer screen shots
showing the operation when cars are present on both roads.

Part e) Debug your combined hardware/software system on the actual LaunchPad board.

[email protected] 10/2/2017
Page 20 Embedded Systems: Introduction to the MSP432 Microcontroller

Demonstration
During checkout, you will be asked to show the system to the TA. The TAs will expect you to know how the
SysTick_Wait function works, and know how to add more input signals and/or output signals. An interesting question that
may be asked during checkout is how you could experimentally prove your system works. In other words, what data should
be collected and how would you collect it? If there were an accident, could you theoretically prove to the judge and jury that
your software implements the FSM? What type of FSM do you have? What other types are there? How many states does it
have? In general, how many next-state arrows are there? Explain how the linked data structure is used to implement the FSM.
Explain the mathematical equation used to calculate the address of the next state, depending on the current state and the
input. Be prepared to write software that delays 1 second without using the timer (you can use a calculator and manual). How
do you prove the delay will be 1 second? What does it mean for the C compiler to align objects in memory? Why does the
compiler perform alignment? List some general qualities that would characterize a good FSM.

Deliverables
1) Logic analyzer screen shot showing the system running when cars are present on both roads.
2) Circuit diagram (with your name and date) using PCB Artist or EagleCAD
3) Drawing of the finite state machine

10/02/17
Jonathan W. Valvano Derived from EE319K Spring 2015 Page 21

Lab 6. Digital Piano using a Digital to Analog Converter


Preparation
Read Sections 9.1, 9.2, 9.4, 9.6, 10.1, 10.2 and 10.3,
Starter files PeriodicSysTickInts_MSP432
https://www.youtube.com/playlist?list=PLyg2vmIzGxXGxGIgbOrqYWALtXnDvxCCd
http://users.ece.utexas.edu/~valvano/Volume1/E-Book/C13_Interactives.htm
Purpose
There are three objectives for this lab: 1) to learn about DAC conversion; 2) to understand how digital data stored in
a computer could be used to represent sounds and music; 3) to study how the DAC can be used to create sounds.
Programming Requirements
All software for this lab must be written in C. You can debug your code in the simulator but your final code must run
on the board with a DAC circuit. Projects in C are a little different than the assembly projects used for Labs 1 to 4.

System Requirements
Most digital music devices rely on high-speed DAC converters to create the analog waveforms required to produce
high-quality sound. In this lab you will create a very simple sound generation system that illustrates this application of the
DAC. Your goal is to create an embedded system that plays three notes, which will be a digital piano with three keys. The
first step is to design and test a 4-bit binary-weighted DAC, which converts 4 bits of digital output from the MSP432 to an
analog signal. You are free to design your DAC with a precision of more than 4 bits. You will convert the four digital bits to
an analog output using a simple resistor network. During the static testing phase, you will connect the DAC analog output to
your voltmeter and measure resolution, range, precision and accuracy. During the dynamic testing phase you will connect the
DAC output to headphones, and listen to sounds created by your software. It doesnt matter what range the DAC is, as long
as there is an approximately linear relationship between the digital data and the speaker current. The performance score of
this lab is not based on loudness, but sound quality. The quality of the music will depend on both hardware and software
factors. The precision of the DAC, external noise and the dynamic range of the speaker are some of the hardware factors.
Software factors include the DAC output rate and the number of data points stored in the sound data. You can create a 3k
resistor from two 1.5k resistors. You can create a 6k resistor from two 12k resistors.
Static Dynamic
MSP432 testing MSP432 testing
Bit3 Bit3
Bit2 Vout Bit2 I out
Voltmeter
bit1 Bit1
Speaker
Bit0 Bit0

Figure 6.1. DAC allows the software to create music.

The second step is to design a low-level device driver for the DAC. Remember, the goal of a device driver is to
separate what the device does from how it works. What it does means the general descriptions and function prototypes of
DAC_Init and DAC_Out that are placed in DAC.h. How it works means the implementations of DAC_Init and
DAC_Out that will be placed in DAC.c. The third step is to design a low-level device driver for the three keys of the piano.
For example, if you could create public functions Piano_Init and Piano_In, where Piano_In returns a logical key
code for the pattern of keys that are pressed. You may design this driver however you wish, but the goal is to abstract the
details how it works (which port, which pin) from what it does (which key pressed). The fourth step is to organize the sound
generation software into a device driver. You will need a data structure to store the sound waveform. You are free to design
your own format, as long as it uses a formal data structure. Compressed data occupies less storage, but requires runtime
calculation. Although you will be playing only three notes, the design should allow additional notes to be added with minimal
effort. For example, if you could create public functions Sound_Init and Sound_Play(note), where the parameter
note specifies the frequency (pitch) of the sound. For example, calling Sound_Play(Off) makes it silent and calling
Sound_Play(C) plays the note C. A background thread within the sound driver implemented with SysTick interrupts will
fetch data out of your music structure and send them to the DAC. The last step is to write a main program that links the
modules together creating the digital piano.

[email protected] 10/2/2017
Page 22 Embedded Systems: Introduction to the MSP432 Microcontroller

Procedure
Part a) Decide which port pins you will use for the inputs and outputs. Avoid the pins with hardware already connected.
Draw the circuit required to interface the binary-weighted DAC to the MSP432. Design the DAC converter using a simple
resistor-adding technique. A 4-bit binary-weighted DAC uses resistors in a 1/2/4/8 resistance ratio. Select values in the 1.5
k to 240 k range. For example, you could use 1.5 k, 3 k, 6 k, and 12 k. Notice that you could create double/half
resistance values by placing identical resistors in series/parallel. It is a good idea to email a pdf file of your design to your TA
and have him/her verify your design before you build it. You can solder 24 gauge solid wires to the audio jack to simplify
connecting your circuit to the headphones. Plug your headphones into your audio jack and use your ohmmeter to determine
which two wires to connect. You have the option of connecting just the left, just the right, or both channels of the
headphones. Draw interface circuits for three switches, which will be used for the piano keyboard.

For sound on one channel only,


connect middle pin to ground
Figure 6.1. A mono jack has three connections (for one channel connect pin 1 to ground and pin 3 to the DAC output).

Part b) You must write the entire code in C. In addition, if you perform the extra credit, it too should be implemented in C.
Write the C language device driver for the DAC interface. Include at least two functions that implement the DAC interface.
For example, you could implement the function DAC_Init() to initialize the DAC, and the function DAC_Out to send a
new data value to the DAC. Place all code that accesses the DAC in a separate DAC.c code file. Add a DAC.h header file
with the prototypes for public functions. Describe how to use a module in the comments of the header file. Describe how the
module works, how to test the module, and how to change module in the comments of the code file.

Part c) Begin with the static testing of the DAC. You will write a simple main program to test the DAC, similar in style as
Program 6.1. You are free to debug this system however you wish, but you must debug The DAC module separately. You
should initially debug your software in the simulator (Figure 6.3). You can single step this program, comparing digital Data
to the analog voltage at the Vout without the speaker attached (i.e., left side of Figure 6.1).
#include "DAC.h"
int main(void){ uint32_t Data; // 0 to 15 DAC output
Clock_Init48MHz(); // Program 4.6c in the book, 48 MHz
DAC_Init();
for(;;) {
DAC_Out(Data);
Data = 0x0F&(Data+1); // 0,1,2...,14,15,0,1,2,...
}
}
Program 6.1. A simple program that outputs all DAC values in sequence.

Using Ohms Law and fact that the digital output voltages will be approximately 0 and 3.3 V, make a table of the theoretical
DAC voltage and as a function of digital value (without the speaker attached). Calculate resolution, range, precision and
accuracy. Complete Table 6.1 and attach it as a deliverable (alternatively you could enter this data into DACdata.xls).

10/02/17
Jonathan W. Valvano Derived from EE319K Spring 2015 Page 23

Bit3 bit2 bit1 bit0 Theoretical DAC voltage Measured DAC voltage
0

10

11

12

13

14

15

Table 6.1. Static performance evaluation of the DAC (if you implement a 6-bit DAC, then make a table with 16
measurements: 0,1,7,8,15,16,17,18,31,32,33,47,48,49,62,63).

Figure 6.2 shows the static testing using program 6.1. The bottom trace is DAC bit 0.

Figure 6.2. Photograph of the DAC output and debugging monitor. This system uses a 6-bit DAC and a 64-element table.
Notice the DAC is monotonic (each increment of the digital input causes the DAC output to go up. (You only need 4 bits). The
top trace is the 6-bit DAC output (without headphones) and the bottom trace is DAC bit 0.

[email protected] 10/2/2017
Page 24 Embedded Systems: Introduction to the MSP432 Microcontroller

Part d) Design and write the piano keyboard device driver software. These routines facilitate the use of the four piano keys.
Include at least two functions that implement the piano keyboard interface. For example, you could implement the function
Piano_Init() to initialize the switch inputs, and the function Piano_In that returns a logical key code for the pattern of
switches that are pressed. Place all code that directly accesses the three switches in a separate Piano.c code file. Add a
Piano.h header file with the prototypes for public functions. Add comments that describe what it does in the Piano.h file and
how it works in the Piano.c file.

Part e) Design and write the sound device driver software. The input to the sound driver is the pitch of the note to play.
SysTick interrupts will be used to set the time in between outputs to the DAC. Add minimally intrusive debugging
instruments to allow you to visualize when interrupts are being processed. Include at least two functions that implement the
sound output. For example, you could implement the function Sound_Init() to initialize the data structures, calls
DAC_Init, and initializes the SysTick interrupt. You could implement a function Sound_Play(note) that starts sound
output at the specified pitch. Place all code that implements the waveform generation in a separate Sound.c code file. Add a
Sound.h header file with the prototypes for public functions. Add comments that describe what it does in the Sound.h file
and how it works in the Sound.c file. When you wish to play a new note you should write to SYSTICK_STRVR, changing
the interrupt period, without completely initializing SysTick.

One approach to debugging is to attempt to create a sine wave with a constant frequency as shown in Figure 6.3. Just
run the SysTick periodic interrupts and output one DAC value each interrupt. The toggling digital line shows you the
interrupts are happening, and the top sine wave shows your table and DAC output are working.

Figure 6.3. The 4-bit DAC with a 32-element table is used to create a sine wave. In this system, the software was attempting
to create 2093 Hz, and the measured frequency was 2092 Hz. The top trace is the DAC output (without headphones) and the
bottom trace is a debugging monitor that toggles at each SysTick interrupt.

Part f) Write a main program to implement the three-key piano. Make a heartbeat connected to an LED so you can see your
program is running. Document clearly the operation of the routines. Figure 6.4 shows a possible data flow graph of the music
player. Debug the individual components (switch input, static DAC output, SysTick ISR) and then combine the components
together into one system on the MSP432. Debug with an oscilloscope. Take a photograph of the scope traces (like Figures 6.2
and 6.3) to capture the waveform generated by your digital piano. When no buttons are pressed, the output will be quiet.
When Button 1 is pressed, output a sine wave at one frequency. When Button 2 is pressed, output a sine wave at a second
frequency. When Button 3 is pressed, output a sine wave at a third frequency. Only one button will be pressed at a time. The
sound lasts until the button is released.

10/02/17
Jonathan W. Valvano Derived from EE319K Spring 2015 Page 25

Push Piano Sound DAC DAC


buttons interface main interface interface hardware

Sin wave
Table
Figure 6.4. Data flows from the memory and the switches to the speaker.

Figure 6.5 shows a possible call graph of the Lab 6 system. Figure 6.6 is one possible way to implement the extra credit.
Dividing the system into modules allows for concurrent development and eases the reuse of code.

main

Sound driver
Piano driver Init Play ISR
Init In
DAC driver
Init Out

Switch SysTick Speaker


hardware hardware hardware
Figure 6.57. A call graph showing the three modules used by the regular part of Lab 6. Notice the SysTick hardware calls the
SysTick ISR.

main
Music driver
Song Stop ISR
Sound driver
Piano driver Init Play ISR
Init In
DAC driver Timer0A
Init Out hardware

Switch SysTick Speaker


hardware hardware hardware
Figure 6.6. A call graph showing the three modules used by the extra credit part of Lab 6. Notice there are two interrupts.

Part g) Add a debugging monitor to your interrupt service routine. I.e., set a digital output pin high at the start of the ISR and
clear it low at the end of the ISR. The scopes in the lab should have probes attached. For this part you need to use the
oscilloscope debugging tool. Connect one channel to a digital output showing when the interrupts are occurring and a second
channel to the DAC output (without the headphones). Set the oscilloscope to trigger on the digital output occurring in the
ISR. Observe the relationship between software and hardware.

[email protected] 10/2/2017
Page 26 Embedded Systems: Introduction to the MSP432 Microcontroller

Demonstration (both partners must be present, and demonstration grades for partners may be different)
You should be able to demonstrate the three notes. Be prepared to explain how your software works. You should be
prepared to discuss alternative approaches and be able to justify your solution. The TA may look at your data and expect you
to understand how the data was collected and how DAC works. In particular, you should be able to design a DAC with 5 to
10 bits. What is the range, resolution and precision? You will tell the TA what frequency you are trying to generate, and they
may check the accuracy with a frequency meter or scope. TAs may ask you what frequency it is supposed to be, and then ask
you to prove it using calculations. Just having three different sounding waves is not enough, you must demonstrate the
frequency is proper and it is a sinewave (at least as good as you can get with a 4-bit DAC). You will be asked to attach your
DAC output to the scope (part g). Many students come for their checkout with systems that did not operate properly. You may
be asked SysTick interrupt and DAC questions. If the desired frequency is f, and there are n samples in the sine wave table,
what SysTick interrupt period would you use?
This lab mentions 32 samples per cycle. Increasing the DAC output rate and the number of points in the table is one
way of smoothing out the steps that in the DAC output waveform. If we double the number of samples from 32 to 64 to
128 and so on, keeping the DAC precision at 4-bit, will we keep getting a corresponding increase in quality of the DAC
output waveform?

As you increase the number of bits in the DAC you expect an increase in the quality of the output waveform. If we
increase the number of bits in the DAC from 4 to 6 to 8 and so on, keeping the number of points in the table fixed at 32, will
we keep getting a corresponding increase in quality of the DAC output waveform?

Deliverables
1) Circuit diagram showing the DAC and any other hardware used in this lab, PCB Artist or EagleCAD
2) Software Design
Draw pictures of the data structures used to store the sound data
If you organized the system different than Figure 6.4 and 6.5, then draw its data flow and call graphs
3) A picture of the dual scope (part g) like Figures 6.3 or 6.4.
4) Measurement Data
Show the theoretical response of DAC voltage versus digital value (part c, Table 6.1)
Show the experimental response of DAC voltage versus digital value (part c, Table 6.1)
Calculate resolution, range, precision and accuracy
5) Brief, one sentence answers to the following questions
When does the interrupt trigger occur?
In which file is the interrupt vector?
List the steps that occur after the trigger occurs and before the processor executes the handler.
It looks like BX LR instruction simply moves LR into PC, how does this return from interrupt?

Extra Credit. Extend the system so that is plays your favorite song (a sequence of notes, set at a specific tempo and includes
an envelope). Your goal is to play your favorite song. The song should contain at least 5 different pitches and at least 20
notes. But, what really matters is the organization is well-done using appropriate data structures that is easy to understand and
easy to adapt for other songs. This extra credit provides for up to 20 additional points, allowing for a score of 120 out of 100
for this lab. 10 possible points for 2 or more extra DAC
bits, and 10 possible points for a song worthy of
dancing. One possible approach is to use two interrupts.
A fast SysTick ISR outputs the sinewave to the DAC
(Figures 6.4 and 6.7). The rate of this interrupt is set to specify the frequency (pitch) of the sound. A second slow Timer ISR
occurs at the tempo of the music. For example, if the song has just quarter notes at 120, then this interrupt occurs every 500
ms. If the song has eight notes, quarter notes and half notes, then this interrupt occurs at 250, 500, 1000 ms respectively.
During this second ISR, the frequency of the first ISR is modified according to the note that is to be played next.
Compressed data occupies less storage, but requires runtime calculations to decompress. On the other hand, a complete list of
points will be simpler to process, but requires more storage than is available on the MSP432. The fourth step is to organize
the music software into a device driver. Although you will be playing only one song, the song data itself will be stored in the
main program, and the device driver will perform all the I/O and interrupts to make it happen. You will need public functions
Song and Stop, which perform operations like a cassette tape player. The Song function has an input parameter that
defines the song to play. If you complete the extra credit (with input switches that can be used to start and stop), then the

10/02/17
Jonathan W. Valvano Derived from EE319K Spring 2015 Page 27

three-key piano functionality still must be completed. In other words, the extra credit part is in addition to the regular part.
You interface more switches (which you can get from checkout) or you could use the on-board switches to activate the Song
and Stop operations

Some web links about music


Simple Music Theory http://library.thinkquest.org/15413/theory/theory.htm
Free sheet music http://www.8notes.com/piano/

Figure 6.7. A song being played with a harmony and melody (see two peaks in the spectrum).

Figure 6.8. This waveform sounds like a horn (6-bit DAC, 64-element table). The top trace is the 6-bit DAC output (without
headphones) and the bottom trace is a debugging monitor that toggles at each SysTick interrupt.

There should be no DAC_Out in the main loop. There should be zero or one DAC_Out each execution of the ISR. Some
students will discover they can make sounds without interrupts, by simply using a software delay like Labs 4, and 5. This
approach is not allowed. Other students will discover they can create sounds by performing the DAC_Out in the main loop.
This approach is also not allowed. 20 point Lab 6 point deduction if zero or one calls to DAC_Out do not occur in the ISR.
These other approaches are not allowed because we will be employing sounds in Lab 10, and we will need the sound to
completely run within the ISR. The Lab 10 main program will start and stop sounds, but the ISR will do all the DAC_Out
calls.

[email protected] 10/2/2017
Page 28 Embedded Systems: Introduction to the MSP432 Microcontroller

Soldering Guide
Reference: John Hewes 2006, The Electronics Club, www.kpsec.freeuk.com
Safety Precautions
Do not solder if you are pregnant or think you might be pregnant
Never touch the element or tip of the soldering iron.
They are very hot (about 400C) and will give you a nasty burn.
Take great care to avoid touching any metal parts of the iron.
The iron should have a heatproof flex for extra protection.
Always return the soldering iron to its stand when not in use.
Never put it down on your workbench, even for a moment!
Allow joints a minute or so to cool down before you touch them.
Work in a well-ventilated area.
The smoke formed as you melt solder is mostly from the flux and quite irritating. Avoid breathing it by keeping you
head to the side of, not above, your work.
Wash your hands after using solder.
Solder contains lead.

Treatment for minor burns


Most burns from soldering are likely to be minor and treatment is simple:
Immediately cool the affected area under gently running cold water.
Keep the burn in the cold water for at least 5 minutes (15 minutes is recommended). You do not wish to freeze the
tissue, so running water is much better than ice.
Do not apply any creams or ointments.
The burn will heal better without them. A dry dressing, such as a clean handkerchief, may be applied if you wish to
protect the area from dirt.
Seek medical attention if the burn breaks the skin.

Preparing the soldering iron


Place the soldering iron in its stand and plug in.
The iron will take a few minutes to reach its operating temperature of about 400C.
Dampen the sponge in the stand.
The best way to do this is to lift it out the stand and hold it under a cold tap for a moment, then squeeze to remove
excess water. It should be damp, not dripping wet. Dont put the
electronics near the tap water
Wait a few minutes for the soldering iron to warm up.
You can check if it is ready by trying to melt a little solder on the
tip.
Wipe the tip of the iron on the damp sponge.
This will clean the tip.
Melt a little solder on the tip of the iron.
This is called 'tinning' and it will help the heat to flow from the
irons tip to the joint. It only needs to be done when you plug in
the iron, and occasionally while soldering if you need to wipe the
tip clean on the sponge.

Preparation
You have two hands.
One hand will hold the iron and the second hand will hold the solder. This means everything else must be
immobilized.
Immobilize the two ends to be soldered such the two ends are in physical contact.
In EE319K we will be soldering a wire to a component. One simple way is to 1) use masking tape to fix the
component to a ceramic tile; 2) cut and strip solid wire; and 3) use masking tape to hold the wire so that the two
metallic parts are touching. Another approach is to 1) cut and strip solid wire; and 2) tightly wrap the stripped
portion of the wire around the component.

10/02/17
Jonathan W. Valvano Derived from EE319K Spring 2015 Page 29

Making soldered joints


Hold the soldering iron like a pen, near the base of the handle.
Imagine you are going to write your name! Remember to never touch the hot element or tip.
Touch the soldering iron onto the joint to be made.
Make sure it touches both the component lead and the track. Hold the tip there for a few seconds and...
Feed a little solder onto the joint.
It should flow smoothly onto the lead and track to form a
volcano shape as shown in the diagram below. Make sure
you apply the solder to the joint, not the iron. Good Bad
Remove the solder, then the iron, while keeping the joint still.
Allow the joint a few seconds to cool before you move
-volcano -ball, bumpy
the circuit board. -shiny -dull
Inspect the joint closely.
It should look shiny and have a volcano shape. If not,
you will need to reheat it and feed in a little more solder.
This time ensure that both the lead and track are heated
fully before applying solder.
Soldering advice for components
Some components require special care when soldering.
Many must be placed the correct way round and a few are easily damaged by the heat from soldering. Appropriate
warnings are given in the following, together with other advice which may be useful when soldering.

Components Pictures Advice


Resistor No special precautions are required. Connect
either way round.
Diodes Diodes must be connected the correct way
round: a = anode, k = cathode. Use a heat
sink with germanium diodes.
a k
Chip holder Ensure the notch is at the correct end. Do
not insert the IC at this stage to prevent it
being damaged by heat.
Ceramic, or nonpolarized No special precautions are required. Connect
capacitor either way round. Take care to identify their
value.

Electrolytic or polarized - + Electrolytic capacitors must be connected


capacitor + the correct way round, they are marked with
+ or - near one lead.
LED a LEDs must be connected the correct way
k round: a = anode (+), k = cathode (-).
flat
Transistors Transistors have three leads and must be
connected the correct way round.

Integrated circuits When all soldering is complete, carefully


insert ICs the correct way round in their
holders. Make sure all the pins are lined up
before pushing in firmly.

[email protected] 10/2/2017
Page 30 Embedded Systems: Introduction to the MSP432 Microcontroller

Lab 7C. LCD Device Driver for the Sitronix ST7735


Preparation
Read Sections 7.1, 7.2, 7.3, 7.4, 7.5, 7.6, and 7.7
Read the data sheet for the LCD display (in project folder)
1-8-tft-display.pdf, ST7735R_V0.2.pdf
Nokia5110_MSP432 or ST7735_MSP432

Purpose
This lab has these major objectives: 1) to interface an LCD interface that can be
used to display information on the embedded system; 2) to use indexed addressing
to access strings; 3) to learn how to design implement and test a device driver
using busy-wait synchronization; 4) to learn how to allocate and use local
variables on the stack; 5) to use fixed-point numbers to store non-integer values.

In Spring 2015, we switched from the monochrome Nokia 5510 to the color
ST7735 because it will make the Lab 10 game more exciting.
Figure 7.1. Sitronix ST7735
System Requirements
In this lab you will interface a Sitronix ST7735 LCD to the MSP432 as shown in Program 7.1.

// pin 10 Backlight +3.3 V


// pin 9 MISO unconnected
// pin 8 SCK P9.5 (Clk)
// pin 7 MOSI P9.7 (SIMO)
// pin 6 TFT_CS P9.4 (STE)
// pin 5 CARD_CS unconnected
// pin 4 D/C P9.2 (GPIO)
// pin 3 RESET P9.3 (GPIO)
// pin 2 VCC +3.3 V
// pin 1 Gnd ground
Program 7.1. Interface connections for the Sitronix ST7735.

D/C stands for data/command; you will make D/C high to send data and low to send a command. This lab will use busy-
wait synchronization, which means before the software issues an output command to the LCD, it will wait until the display
is not busy. In particular, the software will wait for the previous LCD command to complete. For the 10ms wait function, we
suggest you use the cycle-counting approach to blind wait (like Lab 2) instead of SysTick (like Lab 5) because you will need
SysTick periodic interrupts for Labs 8, 9, and 10.

The objective of this lab is to develop a device driver for the Sitronix ST7735 LCD display. A device driver is a set of
functions that facilitate the usage of an I/O port. In particular, there are three components of a device driver. First component
is the description of the driver. Since this driver will be developed in assembly, your descriptions are placed in the comments
before each subroutine. In Labs 8, 9, 10, we will call these driver functions from C, so we also place the function prototypes
for the public functions in the header file LCD.h. It is during the design phase of a project that this information is specified.
The second component of a device driver is the implementation of the functions that perform the I/O. If the driver were being
developed in C, then the implementations would have been placed in the corresponding code file, e.g., LCD.C. When
developing a driver in assembly, the implementations are the instructions and comments placed inside the body of the
subroutines. In addition to public functions, a device driver can also have private functions. This interface will require a
private function that outputs to commands to the LCD (notice that private functions do not include LCD_ in their names).In
this lab, you are required to develop and test seven public functions (notice that public functions include LCD_ or IO_ in
their names). The third component is a main program that can used to test these functions.

In the IO.s file you will implement and test three functions to handle a user switch and heartbeat LED.

10/02/17
Jonathan W. Valvano Derived from EE319K Spring 2015 Page 31

;------------IO_Init------------
; Initialize GPIO Port for a switch and an LED
; Input: none
; Output: none
; Invariables: This function must not permanently modify registers R4 to R11

;------------IO_HeartBeat------------
; Toggle the output state of the LED.
; Input: none
; Output: none
; Invariables: This function must not permanently modify registers R4 to R11
IO_HeartBeat

;------------IO_Touch------------
; First, wait for the key to be released, and then
; wait for the key to be touched
; Input: none
; Output: none
; This is a public function
; Invariables: This function must not permanently modify registers R4 to R11

In the LCD.s file you will implement and test two functions to communicate directly with the Sitronix ST7735 LCD. You
will not write the initialization ritual, because it is given in the ST7735.c file. However you will write these two functions
that output to the LCD. Your writecommand function will be used to output 8-bit commands to the LCD, and your
writedata function will be used to output 8-bit data to the LCD.

; This is a helper function that sends an 8-bit command to the LCD.


; Input: R0 8-bit command to transmit
; Output: none
; Assumes: SPI has already been initialized and enabled
writecommand
;1) Read UCA3IFG and check UCA3TXBUF,
;2) If bit 1 is low, loop back to step 1 (wait for UCA3TXBUF empty)
;3) Clear D/C to zero
;4) Write the command to UCA3TXBUF
;5) Read UCA3IFG and check UCA3TXBUF,
;6) If bit 1 is low, loop back to step 5 (wait for UCA3TXBUF empty)

; This is a helper function that sends an 8-bit data to the LCD.


; Input: R0 8-bit data to transmit
; Output: none
; Assumes: SPI has already been initialized and enabled
writedata
;1) Read UCA3IFG and check bit 1,
;2) If bit 1 is low loop back to step 1 (wait for UCA3TXBUF empty)
;3) Set D/C to one
;4) Write the 8-bit data to UCA3TXBUF

Built on top of your LCD.s file is the c file ST7735.c, which implements 6 public functions that can be used to display
characters and graphics on the display. You should not modify the ST7735.c file. One of the functions, LCD_OutChar,
outputs one ASCII character on the display. In your file print.s, you will implement and test two more display functions.
Your LCD_OutDec function will be used to output an unsigned 32-bit integer to the LCD, and your LCD_OutFix function
will be used to output an unsigned 32-bit fixed-point number to the LCD.

[email protected] 10/2/2017
Page 32 Embedded Systems: Introduction to the MSP432 Microcontroller

;-----------------------LCD_OutDec-----------------------
; Output a 32-bit number in unsigned decimal format
; Input: R0 (call by value) 32-bit unsigned number
; Output: none
; Invariables: This function must not permanently modify registers R4 to R11
LCD_OutDec (R0 is a 32-bit n) You may implement this using either iteration or recursion. You must have at least one
local variable, allocated on the stack, and use symbolic binding for the local. If you use recursion, the base case (n<10)
requires one call to LCD_OutChar. You can use SP or stack frame register for accessing the local variable.

; -----------------------LCD_OutFix----------------------
; Output characters to LCD display in fixed-point format
; unsigned decimal, resolution 0.001, range 0.000 to 9.999
; Inputs: R0 is an unsigned 32-bit number
; Outputs: none
; E.g., R0=0, then output "0.000 "
; R0=3, then output "0.003 "
; R0=89, then output "0.089 "
; R0=123, then output "0.123 "
; R0=9999, then output "9.999 "
; R0>9999, then output "*.*** "
; Invariables: This function must not permanently modify registers R4 to R11
LCD_OutFix (R0 is a 32-bit num) You must have at least one local variable, allocated on the stack, and use symbolic
binding for the local. You can use SP or stack frame register for accessing the local variable.

Parameter LCD display


0 0.000
1 0.001
999 0.999
1000 1.000
9999 9.999
10000 or more *.***
Table 7.1. Specification for the LCD_OutFix function (do not display the quotes).

An important factor in device driver design is to separate the policies of the interface (how to use the programs, which are
defined in the comments placed at the top of each subroutine) from the mechanisms (how the programs are implemented,
which are described in the comments placed within the body of the subroutine.)

The third component of a device driver is a main program that calls the driver functions. This software has two purposes. For
the developer (you), it provides a means to test the driver functions. It should illustrate the full range of features available
with the system. The second purpose of the main program is to give your client or customer (e.g., the TA) examples of how to
use your driver.

Procedure
The basic approach to this lab will be to first develop and test each component separately. During this phase of the project
you will use the debugger to observe your software operation. After each component is debugged, you will combine the
components into one system on the MSP432. There are many functions to write in this lab, so it is important to develop the
device driver in small pieces. One technique you might find useful is desk checking. Basically, you hand-execute your
functions with a specific input parameter. For example, using just a pencil and paper think about the sequential steps that will
occur when LCD_OutDec or LCD_OutFix processes the input 187. Later, while you are debugging the actual functions on
the debugger, you can single step the program and compare the actual data with your expected data.

Part a) This lab is sufficiently complex that we require you to debug the three LCD.s programs first. If your writedata
and writecommand functions in LCD.s are correct, the main program will output the "Lab 7, welcome to 319K!"
message on LCD screen, as shown in Figure 7.2. When print.s is correct, the LCD will show both a decimal number and a
fixed point number, see Figure 7.3. The TestData array in the Lab7Main.s file lists the test values for print.s.

10/02/17
Jonathan W. Valvano Derived from EE319K Spring 2015 Page 33

Part b) To test the hardware display, you can download and run the ST7735_MSP432 example. Do not use the
ST7735_MSP432 project to build your lab 7 solution, but it can be run to make sure your LCD and wiring are correct.

Part c) Test each function separately in the debugger. See Figure 7.2. Your LCD_OutDec and LCD_OutFix functions
must use local variables with binding. To observe the stack when assembly programs are running, set the memory view to
observe 0x200003c0, and the type to be unsigned long. This will show you to top 16 elements on the stack. Successive
refinement is a development approach that can be used to solve complex problems. If the problem is too complicated to
envision a solution, you should redefine the problem and solve an easier problem. If it is still too complicated, redefine it
again, simplifying it even more. You could simplify LCD_OutFix
1) implement the variables in registers (rather than as local variables on the stack)
2) ignore special cases with illegal inputs
3) implement just one decimal digit
During the development phase, you implement and test the simpler problem then refine it, adding back the complexity
required to solve the original problem. You could simplify LCD_OutDec in a similar fashion.

Figure 7.2. The Sitronix ST7735 is a low-cost LCD with 160x128 pixels.

Demonstration (both partners must be present, and demonstration grades for partners may be different)
You will also be required to demonstrate the proper operation on the actual microcontroller. During demonstration to
the TA, you will run your system in the debugger and show the binding, allocation /initialization, access and deallocation of
the local variables. Each time a function is called, an activation record is created on the stack, which includes parameters
passed on the stack (none in this lab), registered saved, and the local variables. You will be asked to observe the stack in the
debugger and identify the activation records created during the execution of LCD_OutDec. TAs may ask you questions on
LCD interfacing, and programming. What is the difference between post and pre-increment modes of addressing? What does
the D/C signal line on the LCD signify? What does busy-wait synchronization mean in the context of communication with
the LCD? The TA will ask to see your implementation local variables and ask you to explain the four step process (binding,
allocation, access and deallocation). You should be able to draw stack pictures. How does AAPCS apply to this lab? Why is
AAPCS important?

Deliverables
1) All source files that you have changed or added (LCD.s, IO.s and print.s)

Hints
1) It will be important to pass data into your functions in Register R0; this way you will be able to call your
functions from C code later in Labs 8, 9, and 10. It is important to save and restore Registers R4-R11 if you use them.
2) You must use the cycle-counting approach to implement the blind waits (Lab 2) instead of SysTick (Lab 5)
because you will need SysTick periodic interrupts for Labs 7, 8, and 9.
3) Because there is a blind cycle synchronization in ST7735.c, Delay1ms so please leave the compiler
optimization on Level 0 and do not click Optimize for Time

[email protected] 10/2/2017
Page 34 Embedded Systems: Introduction to the MSP432 Microcontroller

Lab 8. Real-Time Position Measurement System


Preparation,
Read Sections 9.1, 9.2, 9.3, 9.4, 9.6, 9.8, 10.1, 10.4, and 10.6
ADCSWTrigger_MSP432, ADC_Resolution_MSP432
Make a copy of your Lab7 and rename it Lab8

Purpose
This lab has these major objectives: 1) an introduction to
sampling analog signals using the ADC interface; 2) the development of
an ADC device driver; 3) learning data conversion and calibration
techniques; 4) the use of fixed-point numbers; 5) the development of an
interrupt-driven real-time sampling device driver; 6) the development of a software system involving multiple files and a
mixture of assembly and C; and 7) learn how to debug one module at a time.

System Requirements
You will design a position meter. Your software will use the 14-bit ADC built into the microcontroller. A linear
slide potentiometer (Bourns PTA2043-2015CPB103) converts position into resistance (0 R 10 k). Depending on how
you solder the wires to the pot, the full scale range of position may be anywhere from 1.5 to 2 cm. You will use an electrical
circuit to convert resistance into voltage (Vin). Since the potentiometer has three leads, one possible solution is shown in
Figure 8.1. Add a R1 resistor in the circuit so the input to the ADC ranges from 0 to 2.5V. You may use any ADC channel. The
MSP432 ADC will convert voltage into a 14-bit digital number (0 to 16383). This ADC is a successive approximation device
with a conversion time on the order of several sec. Your software will calculate position from the ADC sample as a decimal
fixed-point number (resolution of 0.001 cm). The position measurements will be displayed on the LCD using the LCD device
driver developed in the Lab 7. A periodic interrupt will be used to establish the real-time sampling. The main program and
SysTick ISR must be written in C. You must use your LCD device drivers that you developed as part of Lab 7. The ADC and
clock system code can be written in either assembly or C, your choice. The device drivers should be in separate files: adc.c,
and clocksystem.c. Each driver file will have a corresponding header file with the prototypes to public functions. The
SysTick initialization, SysTick ISR, mailbox and the main program will be in the main.c file.
+3.3V
MSP432
R1
0 < Vin < 2.5
10k ADC in

Figure 8.1. Possible circuit to interface the sensor (use your ohmmeter on the sensor to find pin numbers 1,2,3).

The left of Figure 8.2 shows a possible data flow graph of this system. Dividing the system into modules allows for
concurrent development and eases the reuse of code. The right of Figure 8.2 shows a possible call graph.
Position Voltage Sample
0 to 2 cm 0 to +2.5V 0 to 16383
Sample
Position ADC ADC 0 to 16383
Sensor hardware driver
SysTick
ISR
SysTick
hardware Mailbox

LCD main
LCD
display driver Fixed-point
0 to 2.000
Figure 8.2. Data flow graph and call graph of the position meter system. Notice the hardware calls the ISR.

10/02/17
Jonathan W. Valvano Derived from EE319K Spring 2015 Page 35

You should make the position resolution and accuracy as good as possible using the 14-bit ADC. The position
resolution is the smallest change in position that your system can reliably detect. In other words, if the resolution were 0.01
cm and the position were to change from 1.00 to 1.01 cm, then your device would be able to recognize the change.
Resolution will depend on the amount of electrical noise, the number of ADC bits, and the resolution of the output display
software. Building a circuit on a breadboard without careful grounding and filtering the system will have signal to noise
equivalent to a 10-bit ADC. Assuming the 10-bit signal to noise ratio (SNR), we expect the resolution to be about 2cm/1024
or about 0.002 cm. Accuracy is defined as the absolute difference between the true position and the value measured by your
device. Accuracy is dependent on the same parameters as resolution, but in addition it is also dependent on the reproducibility
of the transducer and the quality of the calibration procedure. Long-term drift, temperature dependence, and mechanical
vibrations can also affect accuracy.

Figure 8.3. Hardware setup for Lab 8, showing the LCD and slide pot. The slide pot is used to measure distance. the display
you developed in Lab 7. The R1 resistor shown in this figure creates a Vin ranging from 0 to 2.5V.

In this lab, you will be measuring the position of the armature (the movable part) on the slide potentiometer, see Figure
8.3. Due to the mass of the armature and the friction between the armature and the frame, the position signal has a very low
frequency response. One way to estimate the bandwidth of the position signal is to measure the maximum velocity at which
you can move the armature. For example if you can move the armature 2 cm in 0.1sec, its velocity will be 20cm/sec. If we
model the position as a signal sine wave x(t)=1cm*sin(2ft), we calculate the maximum velocity of this sine wave to be
1cm*2f. Therefore we estimate the maximum frequency using 20cm/sec = 1cm*2f, to be 3 Hz. A simpler way to estimate
maximum frequency is to attempt to oscillate it as fast as possible. For example, if we can oscillate it 10 times a second, we
estimate the maximum frequency to be 10 Hz. According to the Nyquist Theorem, we need a sampling rate greater than 20
Hz. Consequently, you will create a system with a sampling rate of 40 Hz. You will sample the ADC exactly every 0.025 sec
and calculate position using decimal fixed-point with of 0.001 cm. You should display the results on the LCD, including
units. In general, when we design a system we choose a display resolution to match the expected measurement resolution.
However in this case, the expected measurement resolution is 0.002 cm, but the display resolution is 0.001 cm. This means
the signal may appear noisy on the display. Electrical noise and uncertainty about exactly the measurement point will
determine accuracy and not the display or the ADC resolution. In most data acquisition systems the noise and transducers are
significant sources of error. A SysTick interrupt will be used to establish the real-time periodic sampling.

Run the project ADC_Resolution_MSP432 with a constant input to see signal to noise ratio of your MSP432. Take a
100 points with a constant input and calculate the standard deviation of the data. Run with SIZE equal to 512, 64, 8, and 1 to
see the relationship between SNR and the size of the digital averaging filter. For more information about this experiment
search the Central Limit Theorem. Roughly stated, as SIZE , the average converges to the expected value.

[email protected] 10/2/2017
Page 36 Embedded Systems: Introduction to the MSP432 Microcontroller

Nyquist Theorem: If fmax is the largest frequency component of the analog signal, then you must sample more
than twice fmax in order to faithfully represent the signal in the digital samples. For example, if the analog signal
is A + B sin(2ft + ) and the sampling rate is greater than 2f, you will be able to determine A, B, f, and from
the digital samples.

Valvano Postulate: If fmax is the largest frequency component of the analog signal, then you must sample more
than ten times fmax in order for the reconstructed digital samples to look like the original signal to the human eye
when plotted on a voltage versus time graph.

When a transducer is not linear, you could use a piece-wise linear interpolation to convert the ADC sample to
position ( of 0.001 cm.) One approach is to use piece-wise linear interpolation. In this approach, there are two small tables
Xtable and Ytable. The Xtable contains the ADC results and the Ytable contains the corresponding positions. The
ADC sample is passed into the lookup function. This function first searches the Xtable for two adjacent of points that
surround the current ADC sample. Next, the function uses linear interpolation to find the position that corresponds to the
ADC sample. You are free to implement the conversion in any acceptable manner, however your conversion function must be
written in C.
A second approach to the conversion is to implement Cubic Interpolation. One description of Cubic Interpolation
can be found in the following document online: http://paulbourke.net/miscellaneous/interpolation/. A third approach,
shown in Figure 8.7, is to fit a linear equation to convert the ADC sample to position ( of 0.001 cm.)

Procedure
The basic approach to this lab will be to debug each module separately. After each module is debugged, you will
combine them one at a time. For example: 1) just the ADC; 2) ADC and LCD; and 3) ADC, LCD and SysTick.
The analog signal connected to the microcomputer comes from a position sensor, such that the analog voltage ranges
from 0 to +3.3V as the position ranges from 0 to Pmax, where Pmax may be any value from 1.5 to 2 cm. The minimum position
is established by where the paper scale is glued to the frame. Glue the paper so that a position of 0 can be measured.
In the final system, you will use SysTick interrupts to establish 40 Hz sampling. In particular, the ADC should be
started exactly every 25 msec. The SysTick ISR will store the 14-bit ADC sample in a global variable (called a MailBox) and
set a flag. Read Section 9.3 in the book to see how a Mailbox can be used to pass data from the background into the
foreground. The main program will collect data from the Mailbox and convert the ADC sample (0 to 16383) into a 32-bit
unsigned decimal fixed-point number, with a of 0.001 cm. Lastly, your main program will use your LCD_OutFix
function from the previous lab to display the sampled signal on the LCD. Include units on your display.

Part a) There are many ways to build a transducer. Your design will require cutting, gluing, and/or soldering. The system in
Figure 8.3 was created by plugging the slide pot into the protoboard and wrapping a solid wire to the armature (to create a
cursor, and gluing a metric ruler on the potientiometer. The example in Figure 8.3 used a Xerox copy of a metric ruler, which
we define as the truth. Another method is to cut out a piece of wood, cardboard, or plastic a little larger than the
potentiometer. Next, you could glue the frame (the fixed part) of the potentiometer to this solid object. Then you could glue
the metric ruler on the frame but near the armature (the movable part) of the sensor. Lastly, you could solder three solid wires
to the slide potentiometer. If you do not know how to solder, ask your TA for a lesson. Pmax will depend on where/how you
solder the wires to the potentiometer.

Please review safety procedures with your instructor, or TA. Please wash your hands after handling the lead solder, please
solder in a well ventilated area, and if you drop the soldering iron let it fall to the ground (dont try to catch it). If you are
pregnant or think you might be pregnant, please do not solder.

Label these three wires +3.3 (Pin3), Vin (Pin2), and ground (Pin1), as shown in Figure 8.1. The potentiometer may have
places where it is nonlinear. The full scale range may be any value from 1.5 to 2.0 cm, depending on your potentiometer.

Part b) You will notice the Lab 8 starter project a main program Lab8.c and three submodules (ST7735, ADC, and
ClockSystem). The main program must be in C, but ADC, and SysTick can be in C or assembly. Each module has a header
file containing the prototypes for public functions (ST7735.h, ADC.h and ClockSystem.h). Use the display you developed in
Lab 7. The right side of Figure 8.4 shows the call graph. The Lab8 (main) calls ADC, ST7735, and TExaS. The ADC module

10/02/17
Jonathan W. Valvano Derived from EE319K Spring 2015 Page 37

accesses the ADC hardware, and the ST7735 module access the SPI and LCD hardware.. The ClockSystem module will
activate the high speed crystal at 48 MHz.

main
SysTick
ISR
Init
ADC driver LCD
SysTick In driver
hardware
ADC LCD
hardware hardware

Figure 8.4. Possible call graph.

Part c) Write two functions: ADC_Init will initialize the ADC interface and ADC_In will sample the ADC. You are free
to pass parameters to these two functions however you wish. You are free to use any of the ADC channels. You are required
to understand every line of the your ADC code. Write main program number 1, which tests these two ADC functions. In this
system, there is no LCD, and there are no interrupts. Debug this system on the real MSP432 to show the sensor and ADC are
operational. The first main program will look something like the following:

#include "ClockSystem.h"
#include "ADC.h"
uint32_t Data;
int main(void){ // single step this program and look at Data
Clock_Init48MHz(); // Bus clock is 48 MHz
ADC_Init(); // turn on ADC,
while(1){
Data = ADC_In(); // sample 14-bit
}
}

Part d) Write main program number 2, which you can use to collect calibration data. In particular, this system should first
sample the ADC and then display the results as unsigned decimal numbers. In this system, there is no mailbox, and there are
no interrupts. You should use your LCD_OutDec developed in the previous lab. Connect PF2 to a real oscilloscope or real
logic analyzer and use it to measure the time it takes the ADC to perform one conversion, and the time it takes the LCD to
output one number. Figure 8.5 shows for this system the ADC requires 9 sec to convert and the LCD requires (you measure
this) sec to display. The second main program will look something like the following:

uint32_t Data;
int main(void){
Clock_Init48MHz(); // Bus clock is 48 MHz
ADC_Init(); // turn on ADC, set channel to 1
LCD_Init();
Port2_Init(); // P2.1 and P2.2 outputs for debugging
while(1){ // scope to measure execution time for ADC_In and LCD_OutDec
P2OUT = 0x04; // Profile ADC
Data = ADC_In(); // sample ADC
P2OUT = 0x00; // end of ADC Profile
LCD_Goto(0,0);
P2OUT = 0x02; // Profile LCD
LCD_OutDec(Data);
LCD_OutString(" "); // these spaces coverup characters from last output
P2OUT = 0; // end of LCD Profile

[email protected] 10/2/2017
Page 38 Embedded Systems: Introduction to the MSP432 Microcontroller

}
}

Figure 8.5. Oscilloscope trace showing the execution time profile. There are a lot of parameters that effect speed, so please
expect your time measurements to be different. For this system it takes 9s for the ADC to sample and 948 s to output.

Collect five to ten calibration points and create a table showing the true position (as determined by reading the position of the
hair-line on the ruler), the analog input (measured with a digital voltmeter) and the ADC sample (measured with main
program 2). The full scale range of your slide pot will be different from the slide pot of the other students, which will affect
the gain (voltage versus position slope). Where you attach the paper ruler will affect the offset. Do not use the data in Table
8.1 (it was generated with a 12-bit ADC on the TM4C123). Collect your own data like the first three columns of Table 8.1.

Position Analog input ADC sample Correct Fixed-point Measured Fixed-point Output
0.10 cm 0.432 538 100 84
0.40 cm 1.043 1295 400 421
0.80 cm 1.722 2140 800 797
1.20 cm 2.455 3050 1200 1202
1.40 cm 2.796 3474 1400 1391
Table 8.1. Calibration results of the conversion from 12-bit ADC sample to fixed-point (collect your own data).

Part e) Use this calibration data to write a function in C that converts a ADC sample into a 32-bit unsigned fixed-point
number. The input parameter (ADC sample) to the function will be passed by value, and your function will return the result
(integer portion of the fixed-point number). Table 8.1 shows some example results; this data is plotted in Figure 8.6. You are
allowed to use a linear equation to convert the ADC sample into the fixed-point number. Please consider overflow and
dropout during this conversion. In this system, the calculation Position = 0.4455*Data-155.38 can be approximated as

Position = (114*Data-39777)/256; // DO NOT USE THESE CONSTANTS, MEASURE YOUR OWN

10/02/17
Jonathan W. Valvano Derived from EE319K Spring 2015 Page 39

Figure 8.6. Plot of the conversion transfer function calculating fixed-point distance as a function of ADC sample.

The third main program will look something like


uint32_t Data; // 14-bit ADC
uint32_t Position; // 32-bit fixed-point 0.001 cm
int main(void){
Clock_Init48MHz(); // Bus clock is 48 MHz
LCD_Init();
Port2_Init(); // P2.1 P2.2 P2.0 outputs for debugging
ADC_Init(); // turn on ADC, set channel to 1
while(1){
P2OUT ^= 0x01; // heartbeat
Data = ADC_In(); // sample ADC
P2OUT |= 0x02; // Profile Convert
Position = Convert(Data);
P2OUT &= ~0x02; // end of Convert Profile
P2OUT = 0x04; // Profile LCD
LCD_Goto(0,0);
LCD_OutDec(Data); LCD_OutString(" ");
LCD_Goto(6,0);
LCD_OutFix(Position);
P2OUT &= ~0x04; // end of LCD Profile
}
}
Part f) Write a C function: SysTick_Init will initialize the SysTick system to interrupt at exactly 40 Hz (every 0.025
second). If you used SysTick to implement the blind wait for the LCD driver, you will have to go back to Lab 7 and remove
all accesses to SysTick from the LCD driver. If you did not use SysTick for the LCD waits, then there is no conflict, and you
can use SysTick code similar to Lab 6 to implement the 25-ms periodic interrupt needed for this lab.

Part g) Write a C SysTick interrupt handler that samples the ADC and enters the data in the mailbox. Using the interrupt
synchronization, the ADC will be sampled at equal time intervals. The toggle a heartbeat LED (P1.0) each time the ADC is
sampled. The frequency of the toggle is a measure of the sampling rate. If you connect the scope to the LED pin, you can also
measure the execution time of the ISR. The interrupt service routine performs these tasks
1) toggle heartbeat LED (change from 0 to 1, or from 1 to 0)
2) toggle heartbeat LED (change from 0 to 1, or from 1 to 0)
3) sample the ADC
4) save the 14-bit ADC sample into the mailbox ADCMail
5) set the mailbox flag ADCStatus to signify new data is available
6) toggle heartbead LED (change from 0 to 1, or from 1 to 0)
7) return from interrupt

[email protected] 10/2/2017
Page 40 Embedded Systems: Introduction to the MSP432 Microcontroller

Part h) Write main program number 4, which initializes the clock system, timer, LCD, ADC and SysTick interrupts. After
initialization, this main program (foreground) performs these five tasks over and over.
1) wait for the mailbox flag ADCStatus to be true
2) read the 14-bit ADC sample from the mailbox ADCMail
3) clear the mailbox flag ADCStatus to signify the mailbox is now empty
4) convert the sample into a fixed-point number (variable integer is 0 to 2000)
5) output the fixed-point number on the LCD with units (LCD_GoTo is faster than LCD_Clear)

After each component has been separately debugged, combine them into one system on the real MSP432. Use a logic
analyzer or oscilloscope to observe the sampling rate. Take a photograph or screen shot of the LED toggling that verifies the
sampling rate is exactly 40 Hz, see Figure 8.7.

Figure 8.7. The oscilloscope connected to the LED pin verifies the sampling rate is 40 Hz. If you were to zoom in, you could
also measure the execution time of the ISR.

Part i) Use the system to collect another five to ten data points, creating a table showing the true position (x ti as determined
by reading the position of the hair-line on the ruler), and measured position (x mi using your device). You can use the
interactive tool at http://users.ece.utexas.edu/~valvano/Volume1/Lab8Accuracy.html to calculate average accuracy by
calculating the average difference between truth and measurement,
1 n
Average accuracy (with units in cm) = x ti x mi
n i 1
True position Measured Position Error
xti xmi xti - xmi

Table 8.2. Accuracy results of the position measurement system.

10/02/17
Jonathan W. Valvano Derived from EE319K Spring 2015 Page 41

Demonstration (both partners must be present, and demonstration grades for partners may be different)
You will show the TA your program operation on the actual MSP432 board. The TA may look at your data and
expect you to understand how the data was collected and how the ADC and interrupts work. You should be able to explain
how the potentiometer converts distance into resistance, and how the circuit converts resistance into voltage. Also be
prepared to explain how your software works and to discuss other ways the problem could have been solved. What will you
change in your program if the potentiometer were to be connected to a different ADC pin? How would this system be
different if the units of measurement were inches instead of cm? Whats your sampling rate? What do you mean by sampling
rate? What is the ADC range, resolution and precision? How do you initialize SysTick interrupt? How can you change your
sampling rate? Be prepared to prove what the sampling rate is using a calculator and the manual. Explain how, when an
interrupt occurs, control reaches the interrupt service routine. Why is it extremely poor style to output the converted data to
the LCD inside the SysTick ISR? Where is the interrupt vector located? What are the differences between an interrupt and a
subroutine? What will happen if you increase your sampling rate a lot? At what point do you think your program will crash?
What is the Nyquist Theorem? How does it apply to this lab?

Deliverables
1) Circuit diagram showing the position sensor, PCB Artist or EagleCAS, like Figure 8.1 (part a),
2) Time measurements and a photo showing the ADC/LCD execution time profile, like Figure 8.6 (part d)
3) Calibration data, like the first three columns of Table 8.1 (part d)
4) A photo or screenshot verifying the sampling rate is 40 Hz, like Figure 8.7 (part h)
5) Accuracy data and accuracy calculation, Table 8.2 (part i)

Hints
1) Debug this lab in parts: debugging each module separately. If you combine two working systems (e.g., ADC and
LCD), you should retest the system.
2) There are lots of details in this lab, please ask your instructor or your TA if you are confused.
3) Use your voltmeter to measure the voltage at the ADC input
4) A useful debugging monitor is to count the number of interrupts (to see if the interrupts are occurring)
5) When running on the MSP432, you cannot use breakpoints effectively in a real-time system like this, because it
takes too long to service a breakpoint (highly intrusive). However, you can dump strategic variables into memory and view
that data in a memory window.
6) It takes a long time for the LCD to initialize. It is necessary to allow the LCD to finish initialization before
starting the SysTick interrupt sampling. One way to do this is to enable interrupts only after all initializations are complete.
7) The fourth column of Table 8.1 is the desired software output, assuming a linear fit between ADC and position.
The fifth column of Table 8.1 is the actual software output using the linear equation implemented as integer operations.

Be careful when connecting the potentiometer to the computer, because if you mistakenly reverse two of the wires, you can
cause a short from +3.3V to ground.

[email protected] 10/2/2017
Page 42 Embedded Systems: Introduction to the MSP432 Microcontroller

Lab 9. Distributed Data Acquisition System


Preparation
Read Sections 8.2, and 11.4 on the UART
Read Sections 11.1, 11.2, and 11.3 on communication systems and the FIFO queues
Download these examples FIFO_MSP432, UART_MSP432, and UARTInts_MSP432
(*****WARNING: YOU ARE RESPONSIBLE FOR EVERY LINE OF CODE IN YOUR SOLUTION except for the LCD
software in ST7735.c/Nokia5110.c and any submodules the software in ST7735.c/Nokia5110.c calls *****).
Make a copy of your Lab8 and rename it Lab9
Teams
To fully test your system you will need two boards. However, you can perform initial testing by connecting the
transmitter output to the receiver input on one board. We suggest you find another group with whom you will finish testing
your system. You will not be checking out the same team as a team with whom you debug. Both groups will have to design,
build and test separate systems. That is you WILL NOT split the lab into two parts with one team working on the Sender and
other working on the Receiver. Each team is responsible for their own system. At the time of checkout, the TA will select
another group with whom you will be checked out. It is also possible for there to be a TA board with which you will check
out. During checkout your system must operate as both a transmitter and a receiver. You cannot share code with other teams
past, present, or future.

Purpose
The objectives of this lab are: 1) to learn how the UART works using both busy-wait and interrupt synchronization;
2) to employ a FIFO queue to buffer data; and 3) to study synchronization issues in a distributed data acquisition system. This
lab is demonstrated on two MSP432 boards.

System Requirements
You will extend the system from Lab 8 to implement a distributed system, see Figure 9.1. In particular, each
MSP432 will sample the data at 40 Hz, transmit the data to the other system, and the other system will display the results on
its LCD. Basically the hardware/software components from Lab 8 will be divided and distributed across two MSP432
microcontrollers. Communication will be full duplex, so the slide pot position will be displayed to the other system.

Figure 9.1. The microcontroller on the right measures position and the one on the left displays the results. In your system
both microcontrollers will have displays and sensors. The data from the left should be displayed on the right, and the data
from the right should be displayed on the left.

Figure 9.2 shows a possible data flow graph of the distributed data acquisition system.

10/02/17
Jonathan W. Valvano Derived from EE319K Spring 2015 Page 43

Position Position
0 to 2 cm 0 to 2 cm
Message
Position STX d1 . d2 d3 d4 CR ETX
Sensor LCD
display
Voltage
0 to +2.5V
ADC
hardware LCD
driver
Sample
0 to 16383 Fixed-point
0 to 2.000
ADC
driver SysTick main
hardware
Sample
0 to 16383 Message Message Message

SysTick UART1 UART1 UART1


ISR driver Tx Rx ISR FIFO
Message
Computer 1
Message Message
Computer 2
Message Message Message
UART1 Rx Tx
UART1 SysTick
FIFO ISR UART1 driver ISR
Message Message Sample
0 to 16383
SysTick
main hardware ADC
driver
Fixed-point Sample
0 to 2.000 0 to 16383
LCD ADC
driver hardware
Voltage
0 to +2.5V
LCD
display Position
Sensor

Position Position
0 to 2 cm 0 to 2 cm
Figure 9.2. Data flows from the sensor on one computer to the LCD on the other computer. SysTick interrupts are used to
trigger the real-time ADC sampling. You will use a 3-wire serial cable to connect the two UART ports. The full scale range of
distance is exactly the same as Lab 8 and depends on the physical size of the slide potentiometer. Shown here as UART1, but
any available UART can be used.

[email protected] 10/2/2017
Page 44 Embedded Systems: Introduction to the MSP432 Microcontroller

A sensor is attached to each computer, and the ADC (ADC_In function) generates a 14-bit digital value from 0 to 16383. The
SysTick periodic interrupt establishes the real-time ADC sampling at 40 Hz. Your convert function will create a calibrated
fixed-point representation of the distance. The calibration conversion occurs on the same computer as the sensor. You will
then encode this information into an 8-byte message and send the message from one computer to the other computer using
the universal asynchronous serial transmitter (UART).

Both the UART transmitter and the UART receiver must use interrupt synchronization. In order to allow your board to
operate with any other students board, we will fix the communication protocol. Each measurement will be sent as exactly
eight serial frames at 100,000 bits/sec:

STX, ASCII1, '.', ASCII2, ASCII3, ASCII4, CR, ETX

For example, if the distance is 1.234 cm, then the following message should be sent.

0x02, 0x31, 0x2E, 0x32, 0x33, 0x34, 0x0D, 0x03

Students can use a 3-pin cable to connect the UART ports between two MSP432 boards. One wire connects the grounds
together, and the other two wires connect Tx to Rx and Rx to Tx. Ask your TA how to connect the cable.

If you were transmitting on a network with more than two nodes, the protocol would need to include the destination address.
Furthermore, if you wanted to transmit other types of data, the protocol would need include data type. If the channel were
noisy, then extra frames could be added to the message to detect and correct errors. Network addressing, message type
specification, data compression, error detection, and error correction are not to be implemented in this lab.

Figure 9.3 shows a possible call graph of the system. The main program will initialize SysTick, the ADC, the FIFO, the LCD
and the UART, but after initialization the main program only performs receiving functions. Notice the race condition where
main can be calling Get at the same time as the UART ISR calls Put. The call graph shows UART1, but you can use any of
the available UARTs. There is no race condition for the shared UART because the transmitting and receiving functions are
separate. Dividing the system into modules allows for concurrent development and eases the reuse of code.

Init Transmitting Receiving


SysTick SysTick main
hardware ISR
Init
Init Out UART driver LCD
In ADC driver ISR Init Get driver
FIFO
ADC UART1 Put LCD
hardware hardware hardware

Figure 9.3. A call graph showing the modules used by the distributed data acquisition system.

Think about what the baud rate means and how it is used. Can you find a mathematical relationship between the ADC
sampling rate (assuming the 8-byte message is transmitted in each sample) and the slowest baud rate possible for the
transmission UART? For example, if I were to reduce the ADC is sampling rate, then I could also reduce the baud rate of the
transmission UART. Think about how the baud rate for the receiver is selected. Is there an advantage to setting the baud rate
of the receiver UART faster or slower than the baud rate of the transmitter? Assume that hardware and software FIFOs are
deep enough to not affect these decisions.

10/02/17
Jonathan W. Valvano Derived from EE319K Spring 2015 Page 45

Procedure (shown below as UART1, but could be any of the available UARTs)
Transmitter software tasks
Part a) Write a C function: UART1_Init that will initialize your UART1 transmitter. This will be similar to book Program
8.1, but with UART1 and with 100,000 bps baud rate. Busy-wait synchronization will be used in the transmitter.
1) enable UART1 transmitter (no interrupts)
2) set the baud rate

Part b) Write a C function: UART1_OutChar for the transmitter that sends one byte using interrupt synchronization. Place
all the UART1 routines in a separate UART1.s or UART1.c file.

Part c) Create a simple array to store the 8 bytes needed for the message. Modify the SysTick interrupt handler from Lab 8 so
that it samples the ADC at 40 Hz and sends the 8-frame message to the other computer using UART1. The SysTick interrupt
service routine performs these tasks
1) toggle a heartbeat (change from 0 to 1, or from 1 to 0),
2) sample the ADC
3) toggle a heartbeat (change from 0 to 1, or from 1 to 0),
4) convert to distance and create the 8-byte message
5) send the 8-byte message to the other computer (calls UART1_OutChar 8 times)
6) increment a TxCounter, used as debugging monitor of the number of ADC samples collected
7) toggle a heartbeat (change from 0 to 1, or from 1 to 0),
8) return from interrupt
Toggling the heartbeat three times allows you to see the LED toggle every 25ms, as well as measure the total execution time
of the ISR using an oscilloscope attached to the heartbeat. To understand the transmitter better answer these questions
Q1) The UART transmitter software has a software FIFO. How deep is the FIFO? (How many frames can it store?)
Q2) At a baud rate of 100,000 bits/sec (1 start, 8 data, 1 stop) how long does it take to send 8 frames?
Q3) The SysTick ISR runs every 25 ms, and each ISR calls UART1_OutChar 8 times. Does this transmit
FIFO ever fill?

Part d) Write a temporary main program for testing the transmitter, which initializes the clock system, SysTick, ADC,
UART1, heartbeat, and enables interrupts. After initialization, this transmitter test main (foreground) performs a do-nothing
loop. This main program will only be used for testing, and will be replaced by a more complex main once the receiver is
built. The ADC sampling and UART1 transmissions occur in the SysTick interrupt service routine running in the background.

To debug the transmitter, you can place the ADC sample and the interrupt counter in a debugger Watch window. The
interrupt TxCounter should increase by 40 every second, and the 14-bit ADC sample should respond to changes in the
slide pot. Attach a dual-channel oscilloscope to the heartbeat and UART outputs, you will see the 8 frames being transmitted
at 100,000 bits/sec every 25 ms. Take two photographs of the scope output, one zoomed in to see the first two frames, and
one zoomed out to see the 25ms time between messages, as shown in Figures 9.4 and 9.5.

[email protected] 10/2/2017
Page 46 Embedded Systems: Introduction to the MSP432 Microcontroller

Figure 9.4. Example scope output measured on the transmitter. The top trace is heartbeat showing the SysTick interrupt has
occurred and the total execution time of the SysTick ISR is 42s. The bottom trace is U1Tx showing the first frame (STX
=0x02, frame is start, bit0, bit1, bit2, bit3, bit4, bit5, bit6, bit7, and stop). The width of bit1 is 10 s, showing the baud rate is
100,000 bits/sec.

Questions to think about:


Q4) If the SysTick ISR sampled the ADC and performed 8 UART outputs, why did this ISR finish in only 42 s?
Q5) Using the photo captured in Figure 9.5, approximately how long does it take to sample the ADC?

Figure 9.5. Example scope output measured on the transmitter. The top trace is PG2 showing the SysTick interrupt is
occurring every 40 ms. The bottom trace is PD2 (U1Tx). The 8 frames of PD2 occur in 800 s, so on this scale one cannot
see the individual frames. (This data is from Spring 2013. Your measurements should show SysTick occurring every 25ms)

Receiver software tasks


Part e) Design, implement and test a C language module implementing a statically allocated FIFO queue. You are allowed to
look at programs in the book and posted on the internet, but you are required to write your own FIFO. Examples of how to
make your FIFO different from the ones in the book include 1) store the data so the oldest is on top and one size counter
defines the FIFO status; 2) implement it so 5, 6, or 8 bytes are put and get at a time; 3) reverse the direction of the pointers so

10/02/17
Jonathan W. Valvano Derived from EE319K Spring 2015 Page 47

both PutPt and GetPt decrement rather than increment; Make sure your FIFO is big enough to hold all data from one
message. Place the FIFO code in a separate fifo.c file. Add a fifo.h file that includes the prototypes for the functions.

The software design steps are


1) Define the names of the functions, input/output parameters, and calling sequence. Type these definitions in as comments
that exist at the top of the functions.
2) Write pseudo-code for the operations. Type the sequences of operations as comments that exist within the bodies of the
functions.
3) Write C code to handle the usual cases. I.e., at first, assume the FIFO is not full on a put, not empty on a get, and the
pointers do not need to be wrapped.
4) Write a main program in C to test the FIFO operations. An example main program is listed below. The example test
program assumes the FIFO can hold up to 6 elements. This main program has no UART, no LCD and no interrupts. Simply
make calls to the three FIFO routines and visualize the FIFO before, during and after the calls. Debug either in the simulator
or on the real board. In this example, Put and Get return a true if successful, Put takes a call by value input, and Get takes a
return by reference parameter. You are free to design the FIFO however you wish as long as it is different from the ones in the
book, and you full understand how it works.
5) Iterate steps 3 and 4 adding code to handle the special cases.

#include fifo.h
int Status[20]; // entries 0,7,12,19 should be false, others true
unsigned char GetData[10]; // entries 1 2 3 4 5 6 7 8 should be 1 2 3 4 5 6 7 8
int main(void){
Fifo_Init();
for(;;){
Status[0] = Fifo_Get(&GetData[0]); // should fail, empty
Status[1] = Fifo_Put(1); // should succeed, 1
Status[2] = Fifo_Put(2); // should succeed, 1 2
Status[3] = Fifo_Put(3); // should succeed, 1 2 3
Status[4] = Fifo_Put(4); // should succeed, 1 2 3 4
Status[5] = Fifo_Put(5); // should succeed, 1 2 3 4 5
Status[6] = Fifo_Put(6); // should succeed, 1 2 3 4 5 6
Status[7] = Fifo_Put(7); // should fail, 1 2 3 4 5 6
Status[8] = Fifo_Get(&GetData[1]); // should succeed, 2 3 4 5 6
Status[9] = Fifo_Get(&GetData[2]); // should succeed, 3 4 5 6
Status[10] = Fifo_Put(7); // should succeed, 3 4 5 6 7
Status[11] = Fifo_Put(8); // should succeed, 3 4 5 6 7 8
Status[12] = Fifo_Put(9); // should fail, 3 4 5 6 7 8
Status[13] = Fifo_Get(&GetData[3]); // should succeed, 4 5 6 7 8
Status[14] = Fifo_Get(&GetData[4]); // should succeed, 5 6 7 8
Status[15] = Fifo_Get(&GetData[5]); // should succeed, 6 7 8
Status[16] = Fifo_Get(&GetData[6]); // should succeed, 7 8
Status[17] = Fifo_Get(&GetData[7]); // should succeed, 8
Status[18] = Fifo_Get(&GetData[8]); // should succeed, empty
Status[19] = Fifo_Get(&GetData[9]); // should fail, empty
}
}

Part f) Write a C function: UART1_Init that will initialize the UART1 receiver for the receiver.
1) clear a global error count, initialize your FIFO (calls Fifo_Init)
2) enable UART1 receiver (arm interrupts for receiving)
3) set the baud rate to 100,000 bits/sec
In general, one must enable interrupts in order for UART1 interrupts to occur. It is good style however to finish all
initializations, then enable interrupts from the high-level main program. The receiver initialization with interrupts should be
added to the transmitter initialization using busy-wait.

Part g) Write the UART interrupt handler in C that receives data from the other computer and puts them into your FIFO
queue. Your software FIFO buffers data between the ISR receiving data and the main program displaying the data. If your
software FIFO is full, increment a global error count. If you get software FIFO full errors, then you have a bug that must be

[email protected] 10/2/2017
Page 48 Embedded Systems: Introduction to the MSP432 Microcontroller

removed. Do not worry about software FIFO empty situations. The software FIFO being empty is not an error. Define the
error count in the UART.c file and increment it in the UART ISR.

Arm it so am interrupt occurs when there is a new receive frame. The interrupt service routine performs these tasks
1) toggle a heartbeat (change from 0 to 1, or from 1 to 0),
2) toggle a heartbeat (change from 0 to 1, or from 1 to 0),
3) Read the data bytes from the UART
4) Put the data into your software FIFO
If your software FIFO is full (data lost) increment a global error count (but dont loop back)
(the data will be interpreted in the main program)
5) Increment a RxCounter, used as debugging monitor of the number of UART messages received
6) toggle a heartbeat (change from 0 to 1, or from 1 to 0),
7) return from interrupt

Toggling heartbeat three times allows you to see the LED flash with your eyes, as well as measure the total execution time of
the ISR using an oscilloscope attached to heartbeat. Place all the UART1 routines in a separate UART1.s file (or UART1.h
and UART1.c).

Part h) The body of the main program reads data from the FIFO and displays the measurement using the same LCD routines
developed in Lab 7 and used in Lab 8. The main program in this data acquisition system performs these tasks
1) initialize the clock system
2) initialize transmitter functions (ADC, heartbeat, SysTick, UART transmission busy-wait)
3) initialize receiver functions (FIFO, LCD, heartbeat, UART receiver with interrupts)
4) enable interrupts
5) calls your FIFO get waiting until new data arrives. FIFO should return an Empty condition if the main program in the
receiver calls get and the FIFO is empty. For more information on how the ISR and main use the FIFO, read Section 11.3 in
the book and look at the left side of Figure 11.6. Also read Section 11.4 and look the the function UART_InChar in Program
11.6. In this step you keep reading until you receive an STX,
6) output the fixed-point number (same format as Lab 8) with units.
The next five characters gotten from the FIFO should be the ASCII representation of the distance
7) repeat steps 5,6 over and over

To debug the system on one microcontroller, connect the transmitter output to the receiver input. In this mode, the
system should operate like Lab 8, where the sensor position is displayed on the LCD. Use the oscilloscope to visualize data
like Figures 9.4 and 9.5.

To debug the distributed system on two microcontrollers, use two PC computers close enough together so you can
connect the two LaunchPads with the special cable, yet run the debugger on both computers. You can place strategic variables
(e.g., ADC sample, interrupt counter) in the Watch windows on both PCs. If you start both computers at the same time all
four interrupt counters should be approximately equal, and the data on both computers should respond to changes in the slide
pot. For the lab to work completely, the transmitter and receivers must receive synchronize properly regardless of which
computer is turned on first, so try turning the boards on/off in different orders and at different times

Demonstration (both partners must be present, and demonstration grades for partners may be different)
You will show the TA your program operation on the two LaunchPad boards. Your TA will connect a scope to either
transmitter heartbeat and TxDRxD or receiver heartbeat and TxDRxD and expect you to explain the relationship
between your executing software and the signals displayed on the scope. Also be prepared to explain how your software
works and to discuss other ways the problem could have been solved. How do you initialize UART? How do you input and
output using UART? What is the difference between busy-wait and interrupt synchronization? What synchronization method
does the transmitter UART use? What synchronization method does the receiver UART use? Explain each bit in the
UCAxIFG register. How and when are these bits set? How and when are these bits cleared? What does the clock system do?
What are the tradeoffs between calling Clock_Init48MHz versus not calling it? Why are there two software FIFOs in this
system? There are lots of FIFO code in the book and on the web that you are encouraged to look at, but you are responsible
for knowing how your FIFO works. What does it mean if each FIFO is full? Empty? What should your system do if the FIFO
is full when it calls PUT? Why? What should your system do if the FIFO is empty when it calls GET? Why?

10/02/17
Jonathan W. Valvano Derived from EE319K Spring 2015 Page 49

Deliverables
1) A circuit diagram showing position sensor, the UART, and the LCD.
2) Two photographs of a scope trace showing serial transmission data, like Figures 9.4 and 9.5.

Hints
1) You should be able to debug your system with any other group. You are not allowed to look at software written by another
group, and you certainly are not allowed to copy software from another group. You are allowed to discuss strategies,
flowcharts, pseudocode, and debugging techniques.
2) This system can be debugged on one board. Connect TxD to RxD.
3) This hint describes in more detail how to create a message. Assume the distance is 1.424 and your software calculates the
appropriate integer 1424. First you convert the digits to 1, 4, 2, 4 in a similar way as LCD_OutFix. Next, you make the digits
ASCII 0x31, 0x34, 0x32, 0x34. Add the STX(02), the decimal point (2E), the CR (0D) and ETX (03), and the message will
be 0x02, 0x31, 0x2E, 0x34, 0x32, 0x34, 0x0D, 0x03. To send this message you call UART_OutChar 8 times using busy-
wait. These 8 bytes will go in the software FIFO of the UART transmitter. The 8 bytes will be sent one at a time, one byte
every 100usec.
4) In order to synchronize the computers regardless of which one is turned on first, the receiver must search a variable
number of input frames until it finds an STX. After receiving an STX, the next 7 frames are a message. Furthermore, the
receiver should discard messages that are not properly formatted (e.g., no decimal point, decimal digits, CR, or ETX)

Figure 9.7. Logic analyzer trace showing heartbeat in the transmitter ISR, the serial line, and heartbeat in the receiver ISR.
Time to execute the transmitter ISR is 14us, the time to send the message is 800us, and the time to execute the receiver ISR is
10us. This data was collected on a LM3S1968 doing a similar lab; your data will look a little different.

[email protected] 10/2/2017
Page 50 Embedded Systems: Introduction to the MSP432 Microcontroller

Lab 10. Embedded System Design


Preparation
Use your Lab8 or Lab9 project as a starter code.
See the material in the GameFiles folder within the MSP432 example projects download

Restrictions on cost
To win the competition, you are restricted to only use parts that were given to you as part of one of the other labs,
plus additional resistors to make more bits in your DAC. If you wish to use extra parts not given as one of the labs, such as
joy sticks, speaker, and amplifiers, you may do so, but will be disqualified from winning the competition, unless specifically
approved by your professor.

Teams
Lab 10 will be performed in teams of two.

Purpose
The objectives of this lab are: 1) design, test, and debug a large C program; 2) to review I/O interfacing techniques
used in this class; and 3) to design a system that performs a useful task. There are four options for Lab 10. Option 1 is to
design a 80s-style shoot-em up game like Space Invaders. Option 2 is to design a turn-based like Connect Four. Option 3
is to design a Pipe Dream game as specified below. The fourth option is to propose an alternative project similar in scope to
these other options. If you would like to propose a project prepare a one-page description by the first Monday after your Lab
9 due date. Good grades will be given to projects that have simple implementations, are functionally complete, and are
finished on time. Significant grade reductions will occur if the project is not completed on time.
Interrupts must be appropriately used control the input/output, and will make a profound impact on how the user
interacts with the game. You could use an edge-triggered interrupt to execute software whenever a button is pressed. You
could output sounds with the DAC using a fixed-frequency periodic interrupts. You could decide to move a sprite using a
periodic interrupt, although the actual LCD output should always be performed in the main program.

System Requirements for all games


There must be at least one externally-interfaced button and one slide pot. Buttons and slide pot must affect game
play. The slide pot must be sampled by the ADC.
There must be at least three images on the LCD display that move in relation to user input and/or time.
There must be sounds appropriate for the game, generated by the DAC
developed in Lab 7. However, the interrupt can be fixed period.
The score should be displayed on the screen (but it could be displayed
before or after the game action).
At least two interrupt ISRs must used in appropriate manners.
The game must be both simple to learn and fun to play.

System Requirements for Space Invaders, Asteroids, Missile Command,


Centipede, Snood, or Defender
You will design, implement and debug 80s or 90s-style video game. You
are free to simplify the rules but your game should be recognizable as one of these
six simple games. Buttons and the slide pot are inputs, and the LCD and sound (Lab
7) are the outputs. The slide pot is a simple yet effective means to move your ship.
Figure 10.1. Space Invaders
http://www.classicgaming.cc/classics/spaceinvaders/index.php

System Requirements for Connect Four


You will design, implement and debug a Connect Four game. Buttons and slide pots are inputs, and the LCD and
sound (Lab 7) are the outputs. The slide pot is a simple yet effective means to select which column to enter your chip. There
are two possible modes for the game. In the required mode, a human plays against artificial intelligence running on the
microcontroller. In addition to the above requirements, Connect Four must also satisfy
The colored pieces must move on the LCD.
You must implement at least a 6-row by 7-column board, but are allowed to create more rows or columns.
Aside from size of the board, you must implement the official Connect Four rules.

10/02/17
Jonathan W. Valvano Derived from EE319K Spring 2015 Page 51

You must check for wins horizontal, vertical, and diagonals. You should also check for a draw.
You must not allow for illegal moves.
The game must have a man versus machine mode.

For more fun, you have the option of creating a two computer mode, where the AI in one microcontroller plays against a
second AI running on a second microcontroller. A similar fun option is having two microcontrollers that allow one human
looking at one display to play against another human looking at a second display. The boards are connected via the UART1
ports, like Lab 9, but with full duplex communication. When running in two computer mode, you need to specify baud rate,
communication protocol, and determine which side goes first. Both computers should recognize that a winner has occurred. If
you implement a two-computer option, it must be done in addition to the required man versus machine mode mode.

System Requirements for Pipe Dream


Pipe Dream is a game played on a grid. The player receives pipe pieces that go on the grid. Possible pieces are a 90
degree turn, a straight piece, and a cross (two straight pieces on top of each other.) Players are given these pieces randomly
and cannot rotate them, and they cannot replace any already placed pieces. Which piece is to be placed next is shown to the
player. The object of the game is to construct a path for water to flow using the pipe pieces given from a designated starting
point on the grid to another designated end point before time runs out. Players receive a score based on how long their final
path of piping was, but if they fail to connect the two points the game will be over. Inputs will select a grid space, and a
single button to place the next piece available in the selected space. There will be a sound for a pipe section being placed, as
well as game over and win sounds. This game must satisfy the System Requirements for all games listed above. Possible
additions include (but not required):
Use two slide pots for moving
Add a queue of pieces that shows not only the next piece to be placed, but the next 3-5 pieces as well
Add obstacles on the grid where pipes may not be placed (or can be placed with a score penalty)
Add already placed pipe sections that give bonus points if used in the solution
Instead of a time limit, have a flow of water start running through the pipes. If the water
gets to an open pipe the player loses, and if the water gets to the end point the player wins.

Figure 10.2 A pipe dream screen.

System Requirements for Design Your Own Project


The first step is to make a proposal. In the Lab10Files folder you will find a proposal for Super Breakout
(SuperBreakout.doc). If selected your game will be added as an official choice that you and other students would be free to
choose. Good projects require students to integrate fundamental class educational objects such as I/O interfacing, data
structures, interrupts, sound, and the effective implementation of real-time activities. This project must satisfy the System
Requirements for all games listed above.

Any TA is authorized to approve an alternate game. If the alternate game is approved the one-page description should be
printed and posted in the lab, and thus available for other students to implement.

Some joysticks provide 2-axis input and are interfaced just like two copies of Lab 8. The interface is simply two slide pots,
which you will need to connect to two ADC channels.

Procedure
Part a) In a system such as this each module must be individually tested. Your system will have four or more modules. Each
module has a separate header and code file. Possible examples for modules include slide pot input, button input, LCD, and
sound output. For each module design the I/O driver (header and code files) and a separate main program to test that
particular module. Develop and test sound outputs as needed for your game. There should be at least one external switch and
at least one slide pot.

Part b) In the game industry an entity that moves around the screen is called a sprite. You will find lots of sprites in the
Lab10Files directory of the starter project. You can create additional sprites as needed using a drawing program like Paint.

[email protected] 10/2/2017
Page 52 Embedded Systems: Introduction to the MSP432 Microcontroller

Most students will be able to complete Lab 10 using only the existing sprites in the starter package. Because of the way
pixels are packed onto the screen, we will limit the placing of sprites to even addresses along the x-axis. Sprites can be placed
at any position along the y-axis. Having a 2-pixel black border on the left and right of the image will simplify moving the
sprite 2 pixels to the left and right without needing to erase it. Similarly having a 1-pixel black border on the top and bottom
of the image will simplify moving the sprite 1 pixel up or down without needing to erase it. You can create your own sprites
using Paint by saving the images as 16-color BMP images. 24-bit BMP images can also be converted, but the files are 8 times
larger and will use up your allotment of 32k on the free version of the compiler. Figure 10.3 is an example BMP image.
Because of the black border, this image can be moved left/right 2 pixels, or up/down 1 pixel. Use the BmpConvert.exe
program to convert the BMP image into a two-dimensional array that can be displayed on the LCD using the function
LCD_DrawBMP(). For this part of the procedure you will need to write main programs for drawing and animating your
sprites.

Figure 10.3. Example BMP file. Each is 16-color, 16 pixels wide by 10 pixels high.

Program 10.1 shows an example BMP file in C program format. There are 0x76 bytes of header data. At locations 0x12-0x15
is the width in little endian format. In this case (shown in blue) the width for this sprite is 16 pixels. At locations 0x16-0x19
is the height also in little endian format.

const unsigned char Enemy10Point1[] = {


0x42,0x4D,0xC6,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x76,0x00,0x00,0x00,0x28,0x00,
0x00,0x00,
0x10,0x00,0x00,0x00, // width is 16 pixels
0x0A,0x00,0x00,0x00, // height is 16 pixels
0x01,0x00,0x04,0x00,0x00,0x00,
0x00,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x80,
0x00,0x00,0x00,0x80,0x80,0x00,0x80,0x00,0x00,0x00,0x80,0x00,0x80,0x00,0x80,0x80,
0x00,0x00,0x80,0x80,0x80,0x00,0xC0,0xC0,0xC0,0x00,0x00,0x00,0xFF,0x00,0x00,0xFF,
0x00,0x00,0x00,0xFF,0xFF,0x00,0xFF,0x00,0x00,0x00,0xFF,0x00,0xFF,0x00,0xFF,0xFF,
0x00,0x00,0xFF,0xFF,0xFF,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // bottom row
0x00,0x0F,0x00,0x00,0x00,0x00,0xF0,0x00,
0x00,0x00,0xF0,0x00,0x00,0x0F,0x00,0x00,
0x00,0x0F,0xFF,0xFF,0xFF,0xFF,0xF0,0x00,
0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,
0x00,0xFF,0xF0,0xFF,0xFF,0x0F,0xFF,0x00,
0x00,0xF0,0xFF,0xFF,0xFF,0xFF,0x0F,0x00,
0x00,0xF0,0x0F,0x00,0x00,0xF0,0x0F,0x00,
0x00,0x00,0xF0,0x00,0x00,0x0F,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // top row
0xFF};
Program 10.1. Example BMP file written as a C constant allocated in ROM.

In this case (shown in red) the height for this sprite is 10 pixels. The LCD LCD_DrawBMP() function restricts the width to
an even number. This function also assumes the entire image will fit onto the screen, and not stick off the side, the top, or the
bottom. There is other information in the header, but it is ignored. As mentioned earlier, you must save the BMP as a 16-color
image. These sixteen colors will map to the grey scale of the LCD. The 4-bit color 0xF is maximum brightness or white, and
the color 0x0 is off or black. Starting in position 0x76, the image data is stored as 4-bit color pixels, with two pixels packed
into each byte. Program 10.1 shows the purple data with 16 pixels per line in row-major. If the width of your image is not a

10/02/17
Jonathan W. Valvano Derived from EE319K Spring 2015 Page 53

multiple of 16 pixels, the BMP format will pad extra bytes into each row so the number of bytes per row is always divisible
by 8. In this case, no padding is needed. The LCD_DrawBMP() function will automatically ignore the padding.

Figure 10.4 shows the data portion of the BMP file as one digit hex with 0s replaced with dots. The 2-D image is stored in
row-major format. Notice in Program 10.1 and Figure 10.4 the image is stored up-side down. When plotting it on the screen
the LCD LCD_DrawBMP() function will reverse it so it is seen right-side up.

................
...F........F...
....F......F....
...FFFFFFFFFF...
..FFFFFFFFFFFF..
..FFF.FFFF.FFF..
..F.FFFFFFFF.F..
..F..F....F..F..
....F......F....
................
Figure 10.4. The raw data from BMP file to illustrate how the image is stored (0s replaced with dots).

Part c) The starter project includes a random number generate. A C version of this function can be found in the book as
Programs 2.6, 2,7, and 3.12. To learn more about this simple method for creating random numbers, do a web search for linear
congruential multiplier. The book example will seed the number with a constant; this means you get exactly the same
random numbers each time you run the program. To make your game more random, you could seed the random number
sequence using the SysTick counter that exists at the time the user first pushes a button (copy the value from the SysTick
counter into the private variable M). You will need to extend this random number module to provide random numbers as
needed for your game. For example, if you wish to generate a random number between 1 and 5, you could define this
function
unsigned long Random5(void){
return ((Random32()>>24)%5)+1; // returns 1, 2, 3, 4, or 5
}
Seeding it with 1 will create the exact same sequence each execution. If you wish different results each time, seed it once
after a button has been pressed for the first time, assuming SysTick is running
Seed(NVIC_ST_CURRENT_R);

Part d) When designing a complex system, it is important to design implement and test low-level modules first (parts a,b,c).
In order to not be overwhelmed with the complexity, you must take two working subsystems and combine them. Do not
combinate all subsystems at the same time. Rather, we should add them one at a time. Start with a simple approach and add
features as you go along.

Step 1) Certification: do this before lab the last week of classes


You will show the TA your program operation on your MSP432 board. The purpose of certification is to certify the
game meets specifications, and to guarantee the zip file is uploaded. Certification will occur during the lab periods and office
hours. There will not be time to certify during the class competition. If your system runs and meets the specifications, it will
be invited to the design competition. The TA will place your game into one or two categories. The wonderful category will
have a maximum of 100 points, and the supreme category has a possible grade of 110 points. We expect most projects to be
invited. The details of the competition will be explained in class. The dute date is 2 hours before the start of the last lecture
class of the semester. Late checkouts are handled by the TA in the usual way. All late checkouts must be completed by Friday
3pm, and all LCDs with the bag must be completed by 5pm Friday.

Step 2) Design competition: occurs during the last class period of the semester (details announced in class)
For each project you will print one page (size 12 font) of some of your Lab 10 code representing software that you
think is well-written and creative. You will pull power from a computer to run your game. One team member will be
stationed at your game to help explain and run your system. The other team member will be given a grading sheet and will
visit/evaluate 8 other projects. The graders should bring their own headphones to minimize the chance of spreading germs.

[email protected] 10/2/2017
Page 54 Embedded Systems: Introduction to the MSP432 Microcontroller

The graders will spend 4 minutes with each project, and then rotate to the next project. The grading is a rank order and will
be secret. The scores should be based on software quality, fun and function. Fun will be had by all.

Step 3) SuperFinals competition: occurs during the last week of classes (details announced in class)
The top scoring game from each class will be invited to the finals. In addition, the TAs will choose a second game from each
class. This will make a total of 6 games for the final. All students from EE319K are invited: cookies and carrots provided.
Each person entering the room will be given ONE voting card. If you are invited to compete, bring your game and a 30
second story of something special about your game. At noon we will write the names of the 6 groups on the white board
making 6 columns
Between at 12:05-12:45 we will demonstrate the games
A) Set up, 1 minute
Plug the audio jack into your device (we will have amplified speakers)
Position the LCD under the document camera
Plug the USB cable into power (we will have USB power)
B) Game play 3 minutes, it is best to talk narrate while you play, helpers allowed
C) Summarize major features so audience will remember you, 30 seconds
D) Disconnect, 30 seconds (at this point you should ceremoniously vote for yourself)

If you have not been invited to compete, and you are proud of your game, bring it and a power source. Set it up and invite
others to play. We expect and encourage talking and walking around.

After the demonstrations have completed, students who wish to vote will cast their vote by placing their ONE card
under/by the name of their favorite project

Hint
1) Say you want to convert a wav file (blah.wav) you want to use in your game. Here are the sequence of steps you can do in
matlab to make this happen:
1. Read the file and extract the sample as well as the frequency:
[Spls, fs] = wavread('blah.wav');
2. Downsample it, to get it to the frequency you want (11.025 kHz):
Spls = downsample(Spls, round(fs/11025));
3. Adjust the samples (originals are fractions between -1 and 1) to range between 0 and 15 (4-bit)
Spls = round((Spls+ 1)* 7.5);
4. write it to a file so you can cut and paste it into your C code:
file = fopen('blah.txt', 'w');
fprintf(file, 'unsigned char blah[] = {');
fprintf(file, '%d,', Spls);
fprintf(file, '};\n');
Thats it, you should have a file (called blah.txt) with a declaration you can cut and paste in your code. There may be an
extra commas in the output that you would have to remove. You could make a convert.m file with these statements inside a
subroutine and have a converter that can be invoked for conversion from matlab. (From Mitch Crooks)

10/02/17

You might also like