setting the frequency of a PWM on a STM32
In short, you want to satisfy the equation:

Prescaler * Overflow = Period-in-Cycles = Clock-cycles-per-Second / Frequency

A good way to calculate the prescaler and overflow values for PWM is to chose the smallest possible prescaler, then trim down the overflow to the desired total frequency. This keeps the overflow value as large as possible, which then gives the most precision if you later want to modulate the duty cycle of the waveform.

For example, if the clock frequency is 72 MHz and you want a 250 Hz output square wave (50% duty), then the total output waveform period in clock cycles (period_cycles) would be 72 MHz / 250 Hz = 288000 cycles. The timer's overflow value is usually 16-bits at most (0xFFFF, or 65535), the prescaler must be such that prescaler * overflow &gt;= period_cycles, and 288000.0 / 0xFFFF =&gt; 4.39459..., so the prescaler should be 5. Finally, 288000 / 5 =&gt; 57600, which is a nice round number for the overflow (you would want to round this to the nearest integer if it wasn't).

Here's some code implementing the above algorithm, including appropriate rounding using C integer arithmetic:

#define CLOCK_CYCLES_PER_SECOND  72000000
#define MAX_RELOAD               0xFFFF

uint32_t period_cycles = CLOCK_CYCLES_PER_SECOND / freq;
uint16_t prescaler = (uint16)(period_cycles / MAX_RELOAD + 1);
uint16_t overflow = (uint16)((period_cycles + (prescaler / 2)) / prescaler);
uint16_t duty = (uint16)(overflow / 2);


Of course, in your actual code you'll want to check for edge cases like freq == 0 or freq &gt; CLOCK_CYCLES_PER_SECOND/2.