STM32 Series Microcontroller - Calculations of Timer Variables

I have deleted my last answer because it was not correct all of the time. I have managed to use this equation to get correct results:

Prescaler = ((((ClockSpeed) / ((period) / (1 / frequency))) + 0.5) - 1);

Factoring Numbers was not the answer.

Here is a simple method I am now using to work out the other variables, Period and Duration.

private void CalculateVariables()
    {
        // Set the Bus Speed (APB1 or APB2), all timers are APB1 except TIM1 and TIM8...
        if (PWMPin == CPU.Pin.Pin7_X3 || PWMPin == CPU.Pin.Pin9_X3 || PWMPin == CPU.Pin.Pin7_X4)
        {
            ClockSpeed = CPU.Clock.APB2;
        }
        else
        {
            ClockSpeed = CPU.Clock.APB1;
        }

        #region Fields...

        uint ONE_MHZ = 1000000;

        uint prescaler = 0;
        uint period = m_period;
        uint duration = m_duration;
        uint scale = ((uint)m_scale);

        // Scale in MHz... 
        uint scaleMHz = scale / ONE_MHZ;

        uint clk = ((uint)ClockSpeed / ONE_MHZ);

        if (duration > period) duration = period;

        #endregion

        #region Calculate Variables (This is a C# implimentation of GHI Source ("PWM_ApplyConfiguration"))...

        prescaler = clk / scale;

        if (prescaler == 0)
        {
            if (period > (0xFFFFFFFF / clk))
            {
                // Avoid Overflow... 
                prescaler = clk;
                period /= scaleMHz;
                duration /= scaleMHz;
            }
            else
            {
                prescaler = 1;
                period = period * clk / scaleMHz;
                duration = duration * clk / scaleMHz;
            }
        }
        else
        {
            while (prescaler > 0x10000)
            {
                // Prescaler too Large... 
                if (period >= 0x80000000) break;
                prescaler >>= 1;
                period <<= 1;
                duration <<= 1;
            }
        }

        bool TimerIs16Bit = true;

        // Were not using Timer 2 of Timer 5...
        if (TimerIs16Bit)
        {
            // All Timers are 16 bit Timer's except 2 and 5... 
            while (period >= 0x10000)
            {
                // period too large 
                if (prescaler > 0x8000) break;
                prescaler <<= 1;
                period >>= 1;
                duration >>= 1;
            }
        }

        #endregion

        if (debug)
        {
            Debug.Print("*** Scale *******");
            // Print to Debug window new config...
            Debug.Print("Period = " + period);
            Debug.Print("Prescaler = " + PrescalerFromPeriodFrequencyAndClock(period, this.Frequency));
            Debug.Print("Duration = " + duration);
        }

        ARRValue = (period - 1);
        PSCValue = PrescalerFromPeriodFrequencyAndClock(period, this.Frequency);
        CCRxValue = duration;
    }

a Simple static Class CPU and I have added:

public enum Pin : int
    {
        Pin7_X3 = 1,
        Pin8_X3 = 2,
        Pin9_X3 = 3,
        Pin7_X4 = 4,
        Pin8_X4 = 5,
        Pin9_X4 = 6
    }

Depending on the clock, prescaler and auto reload, repetition counter (if present) parameters, the 16-bit timer can generate an update event from a nanosecond to a few minutes.

For example, to generate an event two times per second, choose Clock frequency(TIM_CLK) = 168 Mhz, Prescalar(PSC) = 16799, Period(ARR) = 4999, repetition counter(RCR) = 0,

then the 16-bit timer will generate an event two times per second.

enter image description here

For more information ;

STM32 Timer Overview