* : 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.
A comment on the granularity or real resolution of our PWM output
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
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)
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.