Configuring & measuring the MCO on STM32

All ARM Cortex microcontrollers, regardless of vendor or specific core type (M0, M3, etc) have the ability to output one or more of their clocks on one or more pins. This is called Microcontroller Clock Output. This post will look at two MCUs: the STM32F103 and the STM32F207 - both M3 cores.

Using the MCO on STM32 devices is dead simple. It's one function call. That's it.

In the example above, the main system clock (64mhz!) is output on MCO1. On the STM32F103's 48-pin LQFP package, this corresponds to pin PA8. Notice that you don't even have to make the call to __HAL_RCC_GPIOA_CLK_ENABLE() - this is all handled for you by HAL_RCC_MCOConfig.

The STM32F103 can output one of several clocks, including the system clock, internal oscillator or a high speed external oscillator.

On the larger, 100-pin LQFP STM32F207, there are two MCOs which can be configured to output different clocks. In addition, there are more clocks to choose from and you can even divide the clock down a factor of 1 to 5 by passing RCC_MCODIV_x as the final parameter to the MCOConfig function. The F103 does not have this capability.

When I set out to test the MCO output, I ran in to some difficulties measuring the signal on my scope. It has a bandwidth of 100mhz, and the probe is rated for 150mhz - plenty to measure a 64mhz signal. When I first tried to measure the output, I got the result below.

If you look carefully, you'll see that the peak-to-peak voltage is 7.5v. Surprising, given that the system is being fed with only 5v. Also notice that the base voltage dips negative to -700mv. I didn't understand what was happening here, so I asked around. I was told that I was seeing the inherent inductance of the loop created by ground clip inducing ringing in measurement circuit. I was advised to try using the ground spring (it looks like this) rather than the clip. Lo & behold:

The wave is still pretty rough, but it's also switching at 64mhz from the inaccurate internal oscillator so I wouldn't expect to see a clean square wave, either.

Finally, why would you want to do this? I often use MCO output as a sort of hello world when I get a new device I'm not familiar with. Getting MCO working through the vendor's SDK is a good way to verify that you have your toolchain set up correctly. More practically however, you can use MCO to clock other peripherals you have on your board, such as an ethernet PHY.