Lab 4: Digital Audio

Lab 4 employs two timer peripherals within the STM32L432KCU to play Für Elise and Happy Birthday
Author

Thomas Lilygren

Published

September 30, 2025

Introduction

This lab serves as an in-depth introductioin to the STM32L432KCU timer peripherals. Proper configuration of these peripherals allows Fur Elise and Happy Birthday to play based on a set of input frequencies and note durations.

Design and Testing

Timers 15 and 16 were selected to carry out this lab. Timer 15 controls note duration while Timer 16 modulates the frequency for a given input. For both timers, special attention must be paid to the prescalar (PSC) and auto-reload register (ARR) values. The prescalar value divides the 40 MHz input clock and controls measurement resolution, while the auto-reload register value determines the absolute maximum and minimum frequency and duration values that can be achieved at a given prescalar. Both registers for both timers are 16-bits, meaning careful attention must be kept to ensure neither overflows throughout the duration of the songs. For this application, PSC values for both timers were held constant at a value that preserves resolution while modulating the ARR values for the input at a given time. Timer 16 was configured in an alternate mode function for proper GPIO behavior, and the square wave structure relied on the compare-control register to always generate a 50% duty cycle.

Calculations

Both timers operate with 16-bit ARR and PSC registers, so they must be configured carefully to ensure sufficient resolution, allow for proper operation, and avoid overflow risks. Understanding these fundamental restrictions, the operating range for note durations can be determined with Equation 1 and the timing resolution can be calculated with Equation 2.

Both timer operated with 16-bit ARR and PSC registers that must be carefully configured to ensure a full range of operability with reliable resolution measurements. Maximizing the ARR and PSC values at 65535 yields the maximum duration the MCU can play a note and the minimum frequency that note could be. By minimizing these values to 0, the minimum note duration and maximum note frequency can be determined. Refer to Figures 1-4 for these calculations.

TIM15 Calculations

Maximum and Minimum Supported Time

\[ T = \frac{(PSC+1)(ARR+1)}{f_{clk}}\tag{1} \] Max and min for PSC = 0 Max and min for PSC = 399

Timing Resolution

\[ Res = \frac{1}{f_{tim}} = \frac{PSC+1}{40\,MHz}\tag{2} \]

TIM16 Calculations

Maximum and Minimum Supported Frequency

\[ f_{out} = \frac{f_{clk}}{(PSC+1)(ARR+1)} \tag{3} \] Max and min for PSC = 0 Max and min for PSC = 3

Timer duration resolution can be determined by taking the input frequency of 40 MHz and dividing it by the prescalar. Taking this new frequency and taking its inverse yields the time step between counter ticks. This tick resolution should be capabale of handling minute time changes on the millisecond scale. The frequency output should yield less than 1% error for frequencies between 220 and 1000 Hz. For the preset prescalar, the ARR values for these frequency bounds were determined. Since this value can only be an integer, these values were then rounded and the output frequency for those rounded ARR values were computed. Error for each of these frequencies were well within the 1% error bounds as shown in Figure 6.

Frequency Error Calculations

\[ ARR = \frac{f_{clk}}{f_{des}*(PSC+1)}-1 \tag{4} \]

Table 1: Frequency Errors.
Note Freq [Hz] ARR (int) Output Freq [Hz] Error [%]
A3 220.0 45454 219.998 0.0010
A3 \(\sharp\) / B3 \(\flat\) 233.1 42899 233.100 0.0001
B3 246.9 40501 246.901 0.0006
C4 261.6 38225 261.602 0.0008
C4 \(\sharp\) / D4 \(\flat\) 277.2 36074 277.200 0.0001
D4 293.7 34047 293.703 0.0010
D4 \(\sharp\) / E4 \(\flat\) 311.1 32143 311.100 0.0000
E4 329.6 30339 329.598 0.0006
F4 349.2 28636 349.199 0.0004
F4 \(\sharp\) / G4 \(\flat\) 370.0 27026 370.000 0.0001
G4 392.0 25510 392.003 0.0008
G4 \(\sharp\) / A4 \(\flat\) 415.3 24078 415.300 0.0001
A4 440.0 22726 440.005 0.0012
A4 \(\sharp\) / B4 \(\flat\) 466.2 21449 466.200 0.0001
B4 493.9 20246 493.900 0.0001
C5 523.3 19108 523.314 0.0026
C5 \(\sharp\) / D5 \(\flat\) 554.4 18037 554.385 0.0027
D5 587.3 17026 587.303 0.0004
D5 \(\sharp\) / E5 \(\flat\) 622.2 16071 622.200 0.0000
E5 659.2 15169 659.196 0.0006
F5 698.4 14317 698.422 0.0031
F5 \(\sharp\) / G5 \(\flat\) 740.9 13496 740.905 0.0007
G5 784.0 12754 784.006 0.0008
G5 \(\sharp\) / A5 \(\flat\) 830.6 12038 830.634 0.0041
A5 880.0 11363 879.972 0.0032

Technical Documentation

Electric Schematic

Figure 7 displays the electronic schematic for the entire system. The square wave holding the note was output on the PA6 GPIO pin and fed into a potentiometer for volume control. The output from this potentiometer was fed into the LM386 audio amplifier and the sound was produced with an 8-ohm, 4-Watt speaker.

Figure 7: Electronic Schematic

Results and Discussion

This lab meets all excellence specs, providing proper calculations, clear sound, and multiple songs capable of being played. Successful implementation was confirmed by listening to the sound output and using print debug statements to see if the output frequency and durations matched the inputs.

Conclusion

In all, this lab took about 20 productive hours. Aside from familiarizing myself with the timer registers for proper initialization and duty cycle behavior, the biggest setback was not realizing that the GPIO pins must be configured in alternate mode. Once this was figured out, debugging progressed much faster as I could see where the script was problematic.

AI Prototype

ChatGPT’s capability at setting up this lab was tested by prompting:

LLM Prompt

What timers should I use on the STM32L432KC to generate frequencies ranging from 220Hz to 1kHz? What’s the best choice of timer if I want to easily connect it to a GPIO pin? What formulae are relevant, and what registers need to be set to configure them properly?

The AI prepared a promising response, providing accurate formulae, configuring registers with CMSIS, and mentioning proper timers. It ends up choosing Timer 3, which is not concerning, but given its configuration with the CCR1 register, it fails to enable proper outputs that would permit sound to play.

Figure 8: ChatGPT response to AI Prototype Prompt

Figure 9: Response Continued