Page 1 of 1

STM32 Programming. Part 7: MCO Output

Posted: 16 Oct 2023, 03:10
by Oleg
image.png
image.png (8.23 KiB)
Viewed 3585 times
In STM32 microcontrollers the clocking system is quite a tricky thing compared to some AVRs. In this article I will tell you about the MCO pin, through which you can output the microcontroller's internal clock signal outside the microcontroller for clocking any external peripherals.

Here is part of a block diagram showing the MCO:
Figure 1. MCO pin clocking sources
image.png (7.31 KiB)
Figure 1. MCO pin clocking sources Viewed 3585 times
The clock signal to the MCO pin can be supplied from SYSCLK, the HSE and HSI oscillators, and the PLL signal divided in half. In stm32f103c8, the MCO pin is connected to the PA8 port and must be set to alternate function mode before the pin can be used in this mode. The signal source is selected using the MCO bits in the RCC_CFGR register:
Figure 2. MCO bits in the RCC_CFGR register
image.png (18.4 KiB)
Figure 2. MCO bits in the RCC_CFGR register Viewed 3585 times
MCO - supplying a clock signal to the MCO pin of the microcontroller.
  • 0xx: The function is disabled
  • 100: System clock (SYSCLK) selected
  • 101: HSI signal selected
  • 110: HSE signal selected
  • 111: Selected signal from PLL, which is divided by 2.
So, everything seems to be clear: enable GPIOA clocking, set PA8 in the alternative function mode and in the RCC_CFGR register select the source of the clock signal to be output outside. Let's go to implementation The code of the MCO initialization function is very simple, so I will give it all at once:

Code: Select all

//Setting the clock signal output
//through MCO pin
//sourse - clocking source
// 0 - disabled
// 4 - SYSCLK
// 5 - HSI
// 6 - HSE
// 7 - PLL/2
void MCO_Init(int sourse)
{
  if(sourse != 0 && !(sourse >= 4 && sourse <= 7))
    return;
       
  RCC->APB2ENR |= RCC_APB2ENR_IOPAEN; //Enable PA port clocking
  
  //Set the port in the alternative function mode
  GPIOA->CRH &= ~(GPIO_CRH_MODE8_Msk | GPIO_CRH_CNF8_Msk); //Reset bits to zero
  GPIOA->CRH |= (0x03 << GPIO_CRH_MODE8_Pos) | (0x02 << GPIO_CRH_CNF8_Pos); //set desired bits
  
  RCC->CFGR &= ~(RCC_CFGR_MCO_Msk); //Set everything to zero first
  RCC->CFGR |= (sourse<<RCC_CFGR_MCO_Pos); //Set clocking source
}
It should be noted that in this example PA8 is set to a maximum frequency of 50 MHz, and the output signal should not exceed this frequency, i.e. if SYSCLK is 72 MHz, this signal cannot be used for output through PA8. But we will try to do it and see what we get

Check:

Code: Select all

void main()
{
  ClockInit();
  
  // 0 - disabled
  // 4 - SYSCLK
  // 5 - HSI
  // 6 - HSE
  // 7 - PLL/2
  MCO_Init(6);
  for(;;)
  {
  }
}
ClockInit() - initialization of the clocking system, see STM32 Programming. Part 4: Configuring RCC. In the ClockInit() initialization function, I only removed the line at the end with disabling the internal HSI RC oscillator, everything else is the same. Next, MCO_Init(6) we configure the MCO to output the clock signal from the HSE oscillator. Here is the oscillogram:
Figure 3. MCO configured for HSE
image.png (6.26 KiB)
Figure 3. MCO configured for HSE Viewed 3585 times
The oscilloscope shows a frequency of 8 MHz. Next, from the HSI oscillator (MCO_Init(5)):
Figure 4. MCO configured for HSI
image.png (6.13 KiB)
Figure 4. MCO configured for HSI Viewed 3585 times
Here we should have 8 MHz, but the actual value is 8.065. And this value floats noticeably when the temperature of the microcontroller changes. Let's go further: PLL/2:
Figure 5. MCO configured for PLL/2
image.png (6.11 KiB)
Figure 5. MCO configured for PLL/2 Viewed 3585 times
This should be a meander with a frequency of 36 MHz, in fact we see a broken sine with this frequency. My oscilloscope does not pull such frequencies, because its bandwidth is 50 MHz. And lastly, we connect the MCO to SYSCLK, which has a frequency of 72 MHz:

Unfortunately, it is difficult to judge the shape of the signal on PA8, because the frequency of the measured signal exceeds the oscilloscope bandwidth. We should play with the port settings sometime and see how much the MODE bits in the GPIOx_CRy register affect the port output signal shape.