16-bit PWM resolution example (4 lines of code)

Post your cool example code here.
Post Reply
AndrewBCN
Posts: 105
Joined: Sun Apr 25, 2021 3:50 pm
Answers: 1
Location: Strasbourg, France

16-bit PWM resolution example (4 lines of code)

Post by AndrewBCN »

As we all know, for backward compatibility with AVR MCU's, the default resolution for PWM output in STM32 Core is 8-bits, this provides a "granularity" of 1/256 = approx. 0.4%. However, since STM32 MCUs in general implement a number of 16-bit timers, we have the option of setting the PWM resolution to a maximum of 16 bits, providing a "granularity" of not quite*, but almost 1/65536 = approx. 0.0015%. Depending on the application this can be very desirable, and it is rather easy to obtain thanks to the excellent STM32 Wire library.
* : see explanation below

The following example uses Timer 4 Channel 4 on an STM32F411CEU6 MCU to generate a 2kHz PWM signal with 16-bit resolution, and all it takes is 4 lines of code.

Code: Select all

  // generate a test 2kHz square wave on PB9 PWM pin, using Timer 4 channel 4
  // PB9 is Timer 4 Channel 4 from Arduino_Core_STM32/variants/STM32F4xx/F411C(C-E)(U-Y)/PeripheralPins_BLACKPILL_F411CE.c
  analogWrite(PB9, 127);      // configures PB9 as PWM output pin at default frequency (1kHz) and resolution (8 bits), 50% duty cycle
  analogWriteFrequency(2000); // default PWM frequency is 1kHz, change it to 2kHz
  analogWriteResolution(16);  // set PWM resolution to 16 bits, default is 8 bits
  analogWrite(PB9, 32767);    // 32767 for 16 bits -> 50% duty cycle so a square wave
A comment on the granularity or real resolution of our PWM output

Now, about the exact "granularity", it is in fact limited by the values in the TIMx->ARR (frequency) and TIMx-> CCRy (duty cycle) registers for the timer x, channel y used.

If we read the register values for the example above, we get:
TIM4->ARR = 48000-1 (because 2kHz = 96MHz / 48000)
and
TIM4->CCR4 = 32767 x 48000/65536 (truncated to the nearest integer, I suppose).

So for these register values in the example above, the real "granularity" is not 1/65536 but somewhat higher 1/48000.
timothyferriss
Posts: 1
Joined: Tue May 16, 2023 9:30 am

Re: 16-bit PWM resolution example (4 lines of code)

Post by timothyferriss »

It's important to keep in mind that the PWM output's real resolution and granularity may differ based on the particular STM32 microcontroller, timer configuration, and desired frequency.
Post Reply

Return to “Code snippets”