stm32hal

STM32: Generate a 22 MHz clock on GPIO out from SystemCoreClock 110 MHz


I want to generate a clock for the PCA9959 LED driver with my STM32L552. The LED driver needs an external clock at 20 MHz (+/- 15%). I'm trying to generate a 22 MHz clock on port PA8 on STM32L552. I managed to generate a PWM on port PA8, but I can't reach the frequency of approximately 22 MHz. I arrive at a maximum of 8 MHz.

Here are the PWM parameters:

TIM configuration

I'm not sure I filled in the PWM parameters correctly. Normally with these settings, I guess I should have a 22 MHz PWM with a 20% duty cycle.

PWM (MHz) = SystemCoreClock (MHz) / prescaler => 22 MHz = 110 MHz / 5

My clock configuration:

Clock configuration


Solution

  • The easiest way to output a high speed clock like this is with the MCO peripheral, rather than a timer. Fortunately for you the MCO pin is PA8. Perhaps the person who designed your board knew this and intended you to use MCO. Read the reference manual to see how.

    If you do want to use a timer to do 22 MHz, then as you have correctly identified you cannot get a 50% duty-cycle on your PWM. I would recommend starting with a 40% or 60%, with an output-compare value of 2-out-of-5 or 3-out-of-5, not 1 as you have above.

    There is no detail in the PCA9959 datasheet about what the required mark-space ratio of the clock is, but I guess anything other than 50% could be a problem. You would be better to divide the clock by an even number. Either just divide 110 MHz by 6 and output 18.33 MHz, or else slow your core down a bit and divide by 4 (reduce the N parameter of your PLL).

    Whether you use MCO or PWM, don't forget to set the GPIO pin mode to the fastest slew rate available. Maybe the 8 MHz you are measuring is the result of aliasing a faster clock that has been through the wrong GPIO mode. You could test this using a scope with at least 100 MHz bandwidth.