Lab 0: Stopwatch
Prerequisites
Section titled “Prerequisites”Introduction
Section titled “Introduction”In this lab, you will:
- Set up your development environment using Code Composer Studio (CCS)
- Explore the TM4C1294XL LaunchPad and BOOSTXL-EDUMKII BoosterPack hardware
- Import and run a starter stopwatch project to verify your environment setup
- Learn how to write modular embedded programs using C/C++ and TI’s driver libraries
To complete each lab in this course, you must:
- Submit your source code for the lab
- Demonstrate your project in operation to one of the course staff (TA or tutor)
- Receive a sign-off after successful demonstration
You will be graded based on the completion of the required steps and correct functionality.
Late submissions will receive a 20% penalty unless otherwise specified by your instructor.
Grading Rubric
Section titled “ Grading Rubric”| Step | Description | Max Points | Score |
|---|---|---|---|
| 1 | Compile and flash the starter stopwatch example (verify environment) | 10 | |
| 2 | Extend the stopwatch to display HH:MM:SS:MS format | 20 | |
| 3 | Implement physical buttons S1 → Play/Pause and S2 → Reset | 35 | |
| 4 | Add on-screen buttons with feedback and state text (Running / Stopped) | 15 | |
| 5 | Source Code — Organization, readability, and modular structure | 20 | |
| Total | 100 |
Objectives
Section titled “Objectives”By the end of this lab, you will have accomplished:
- Install software: Code Composer Studio (CCS) and Free-RTOS
- Set up a CCS project for the EK‑TM4C1294XL + BoosterPack
- Output to the 128×128 LCD display
- Configure general purpose timers and interrupts
- Read and debounce user buttons
- Understand how to import libraries
Key Learning Points
Section titled “Key Learning Points”- Using hardware timers for precise time measurement.
- Managing non‑blocking tasks with
elapsedMillisutilities. - Handling button debouncing and event callbacks.
- Creating simple GUIs using GRLIB primitives.
- Synchronizing display updates with real‑time processes.
Required Materials
Section titled “Required Materials”Before starting this lab, make sure you have the following:
- TI EK-TM4C1294XL LaunchPad Development Kit
- BOOSTXL-EDUMKII BoosterPack
- Micro-USB cable for programming and power
- Lab 0 Template: Download ZIP
Stopwatch Implementation
Section titled “Stopwatch Implementation”Implement a stopwatch with hours, minutes, seconds, and milliseconds, using the S1 button for Play/Pause and S2 for Reset. The application must also show two on‑screen buttons that react to physical button interactions, as well as a text label indicating the current state: Running or Stopped.
Overview
Section titled “Overview”In this lab exercise, you will use a modular C/C++ approach to design a stopwatch running on the TM4C1294XL LaunchPad with the BOOSTXL‑EDUMKII LCD.
The system measures elapsed time using hardware timers and updates the display at a fixed refresh rate.
The application demonstrates:
- Use of timers for precise millisecond tracking.
- Integration of physical button input with graphical feedback.
- Modular code structure using custom libraries (
button.h,timerLib.h,elapsedTime.h). - Real‑time display management with TI GRLIB.
Starter Example
Section titled “Starter Example”You are provided with a simplified starter example that demonstrates how to:
- Initialize the system clock and LCD display.
- Configure a periodic hardware timer using the
Timerclass andelapsedTimeClass. - Use the
Buttonclass to detect press and release events for S1. - Draw on‑screen UI elements such as rectangles and text using GRLIB.
In the provided code:
- S1 toggles between Play and Pause.
- A single on‑screen button labeled PLAY/PAUSE changes color when pressed.
- The display shows the word STOPWATCH and a time counter (in seconds) at the center.
- The background is cleared and redrawn periodically at 20 ms button scan and 50 ms display refresh intervals.
Understanding the Code Structure
Section titled “Understanding the Code Structure”1. System Initialization
Section titled “1. System Initialization”Every embedded program should start by disabling global interrupts and enabling the Floating-Point Unit (FPU). The FPU improves performance when using floating-point arithmetic, which is often needed for signal processing, filters, or calculations involving time.
IntMasterDisable();FPUEnable();FPULazyStackingEnable();Afterward, it is crucial to configure the system clock, as all peripherals (timers, ADC, UART, etc.) depend on it to operate correctly:
gSystemClock = SysCtlClockFreqSet( SYSCTL_XTAL_25MHZ | SYSCTL_OSC_MAIN | SYSCTL_USE_PLL | SYSCTL_CFG_VCO_480, 120000000);This setup uses the 25 MHz external crystal and the PLL (Phase-Locked Loop) to generate a 120 MHz system clock.
2. Display Initialization
Section titled “2. Display Initialization”If the program uses the LCD, the display must be initialized through the graphics context tContext. This block configures the SPI interface and prepares the screen for drawing.
tContext sContext;initializeDisplay(sContext);The display is connected through SPI2, and this helper function configures the GRLIB driver and clears the screen:
static void initializeDisplay(tContext &context){ Crystalfontz128x128_Init(); Crystalfontz128x128_SetOrientation(LCD_ORIENTATION_UP); GrContextInit(&context, &g_sCrystalfontz128x128); GrContextFontSet(&context, &g_sFontFixed6x8);
tRectangle full = {0, 0, 127, 127}; GrContextForegroundSet(&context, ClrBlack); GrRectFill(&context, &full);}3. Timer and Elapsed Time Setup
Section titled “3. Timer and Elapsed Time Setup”Any task that needs to be executed periodically—like reading a sensor, blinking an LED, or updating the display—requires a timer. In this project, Timer0 is used as the reference for the elapsedMillis objects:
Timer timer;configureTimer(timer);
elapsedMillis buttonTick(timer);elapsedMillis displayTick(timer);elapsedMillis stopwatchTick(timer);Each elapsedMillis instance keeps track of elapsed time independently, allowing you to execute tasks at precise intervals without using delays.
The timer configuration function:
static void configureTimer(Timer &timer){ timer.begin(gSystemClock, TIMER0_BASE);}This initializes Timer0 as a system time base synchronized with the configured system clock.
Button Configuration
Section titled “Button Configuration”Each hardware button (S1, S2, or others) must be configured using the Button class before it can be used. The button library handles debouncing and state detection automatically.
static void setupButtons(){ btnPlayPause.begin(); btnPlayPause.setTickIntervalMs(BUTTON_TICK_MS); btnPlayPause.setDebounceMs(30);}After setup, interrupts can be re-enabled:
IntMasterEnable();5. Main Loop Structure
Section titled “5. Main Loop Structure”The main loop (while(true)) is where all recurring tasks are executed in non-blocking intervals. Each task checks its elapsed time counter and executes only when its timer expires.
This pattern ensures that the program remains responsive without delays.
6. Display Drawing Functions
Section titled “6. Display Drawing Functions”It’s recommended to separate the LCD drawing logic into functions for readability and maintainability:
Stopwatch Display
Section titled “Stopwatch Display”Draws the stopwatch title and current time.
static void drawStopwatchScreen(tContext &context, uint32_t currentSec, bool running){ tRectangle rectFull = {0, 0, 127, 127}; GrContextForegroundSet(&context, ClrBlack); GrRectFill(&context, &rectFull);
GrContextForegroundSet(&context, ClrCyan); GrStringDrawCentered(&context, "STOPWATCH", -1, 64, 15, false);
char str[10]; snprintf(str, sizeof(str), "%02u s", currentSec);
GrContextForegroundSet(&context, running ? ClrYellow : ClrOlive); GrStringDrawCentered(&context, str, -1, 64, 50, false);}Button Drawing
Section titled “Button Drawing”Handles rendering of buttons with color changes when pressed.
static void drawButton(tContext &context, const MyButton &btn){ uint16_t bgColor = btn.pressed ? ClrBlack : ClrGray; uint16_t textColor = btn.pressed ? ClrWhite : ClrBlack;
tRectangle rect = {btn.x, btn.y, btn.x + btn.w - 1, btn.y + btn.h - 1}; GrContextForegroundSet(&context, bgColor); GrRectFill(&context, &rect);
GrContextForegroundSet(&context, ClrBlack); GrRectDraw(&context, &rect);
GrContextForegroundSet(&context, textColor); GrStringDrawCentered(&context, btn.label, -1, btn.x + btn.w / 2, btn.y + btn.h / 2, false);}Implementation Tasks
Section titled “Implementation Tasks”You must extend this implementation to complete the full stopwatch behavior:
-
Add a second button (S2)
‑ UseButton btnReset(S2);
‑ When pressed, set the stopwatch time back to zero. -
Expand the time format
‑ Display the time asHH:MM:SS:MS.
‑ Convert milliseconds using division and modulo operations. -
Display the system state
‑ Show a labelRunningorStoppeddepending on the value ofgRunning. -
Add a second on‑screen button for Reset
‑ Create a newMyButtonstruct instance for Reset.
‑ The button should visually change when S2 is pressed. -
Improve display logic
‑ Limit updates to roughly 60 Hz (~16 msbetween redraws).
‑ Only refresh when time, button state, or mode changes. -
Ensure debouncing and callbacks
‑ UsebtnPlayPause.setDebounceMs(30)and similar for the Reset button.
‑ Implement callback functionsonPlayPauseClick(),onResetClick(), etc.
Expected Behavior
Section titled “Expected Behavior”- The stopwatch starts in the Stopped state at
00:00:00:000. - Pressing S1 toggles between Running and Stopped.
- Pressing S2 resets the timer to zero.
- The text label reflects the current state.
- The on‑screen buttons change color briefly when their physical counterparts are pressed.

Example of the stopwatch interface with on‑screen buttons and state indicator
Deliverables
Section titled “Deliverables”Your final stopwatch application must:
- Display the time in
HH:MM:SS:MSformat. - Show
RunningorStoppedbased on the system state. - Respond visually and functionally to both S1 and S2 presses.
- Maintain smooth updates and clean modular code.
Submitting Source Code
Section titled “Submitting Source Code”Exporting project:
- Ensure project named
ece3849_lab0_<username>. - Right‑click the project →
Export...→General→Archive File. - Choose the output path and filename equal to the project name (
ece3849_lab0_<username>.zip). - Upload
.zipto Canvas.
Appendix / Useful Links
Section titled “Appendix / Useful Links”- TI TivaWare: https://www.ti.com/tool/SW-TM4C
- Graphics Library User Guide: https://www.ti.com/lit/ug/spmu300e/spmu300e.pdf
- TM4C1294 Datasheet: https://www.ti.com/lit/ds/symlink/tm4c1294ncpdt.pdf
- EK‑TM4C1294XL: https://www.ti.com/tool/EK-TM4C1294XL
- BoosterPack EDUMKII: https://www.ti.com/tool/BOOSTXL-EDUMKII