Lab #2: USART GPIO and UART

📚 LAB 2 CMPE1250: Advanced Timer Control and PWM

📋 Objective

  • In this lab, you will configure a timer to generate a Pulse Width Modulated (PWM) signal and establish a precise interval. You will use a button board to dynamically scale the period and duty cycle of the PWM signal without using floating-point math, maintaining structural accuracy across state changes.

Hardware Requirements

  • Nucleo-G0B1 Development Board

  • External Button Board (SW1 - SW4)

  • Oscilloscope or AD2(to verify the PWM frequency, duty cycle, and polarity)

Pre-Lab Notes & Constraints

  • System Clock: Configure the system clock to 50MHz (Clock_InitPll(PLL_50MHZ)).

  • Integer Math Only: Do not use float or double variables. To maintain accuracy and execution speed, all percentage calculations for the duty cycle must be done using integer arithmetic.

  • Timer ARR Offset: Remember that the Auto-Reload Register (ARR) value must always be the desired number of ticks minus 1.

  • Polling time: You will use a secondary timer configured for a 25ms time event. All button checks and subsequent PWM updates must occur strictly within this polling window.


1️⃣ Part A: Initial Setup and Period Control

1.1 Hardware Initialization

  • Enable the clocks for GPIO ports A, B, C, and D.

  • Configure the User LED (PA5) as an output.

  • Configure the Blue User Button (PC13) as an input.

  • Configure the button board inputs:

    • SW1: PD8

    • SW2: PC10

    • SW3: PC12

    • SW4: PD9

  • Important: Before writing the logic, physically verify that SW1-SW4 trigger independently. Some damaged button boards may have bridged buttons. TAlk to your instructor to get it replaced if that is the case.

1.2 Timer Configuration

  • Polling Timer: Configure this timer to trigger an update event every 25ms.

  • TIM17 (PWM Timer): Configure PB9 for Alternate Function 2 (TIM17_CH1).

  • Set the prescaler so the timer ticks every 1us.

  • Set the initial period to 500us (yielding a 2kHz frequency) and the initial duty cycle to 50%.

  • Set the Output Compare action to PWM Mode 1.

  • Enable the Output Compare channel and the Main Output Enable (MOE) bit in the BDTR register.

1.3 Dynamic Period Scaling

Using your 25ms timer eventpolling structure, implement the following:

  • Pressing SW3 (PC12): Increase the period by 10us per 25ms tick, up to a maximum of 1000us.

  • Pressing SW2 (PC10): Decrease the period by 10us per 25ms tick, down to a minimum of 100us.

  • Validation: As the period dynamically scales, ensure the duty cycle remains locked at exactly 50%.


2️⃣ Part B: Duty Cycle Control and Polarity Toggling

2.1 Dynamic Duty Cycle Scaling

Expand your polling logic to include duty cycle modifications using SW1 and SW4.

  • Pressing SW4 (PD9): Increase the duty cycle by 1% per 25ms tick, up to a maximum of 99%.

  • Pressing SW1 (PD8): Decrease the duty cycle by 1% per 25ms tick, down to a minimum of 1%.

  • Validation: When you change the period using SW2/SW3, the system must now remember and maintain the current

user-defined duty cycle percentage, rather than reverting to 50%.

2.2 PWM Polarity Toggle

  • Implement a state variable to monitor the Blue User Button (PC13).

  • When PC13 is pressed, toggle the PWM output polarity by switching TIM17 between PWM Mode 1 and PWM Mode 2.

  • This must only trigger once per press (edge detection), requiring you to track the button’s previous state so holding the button does not cause rapid toggling.

Lab Verification Checklist

Demonstrate the following to your instructor using an oscilloscope connected to PB9:

[X] Button Independence: SW1, SW2, SW3, and SW4 actuate their respective values without bridging.

[X] Polling Accuracy: Value changes happen smoothly based on the 25ms interval (toggle PA5 to verify).

[X] Base State: Upon reset, the system generates a 2kHz (500us period) PWM signal at 50% duty cycle.

[X] Period Limits: SW2 and SW3 correctly bottom out at 100us and max out at 1000us.

[X] Proportional Duty Cycle: Adjusting the period maintains the exact percentage of the currently set duty cycle.

[X] Duty Limits: SW1 and SW4 correctly bind the duty cycle between 1% and 99%.

[X] Polarity Toggle: Pressing the Blue Button (PC13) cleanly inverts the PWM signal (switching between PWM1 and PWM2) exactly once per press.