STM32 system clock super detailed explanation

1. What is a clock

1. What is the function of the clock to the microcontroller

The clock is a periodic pulse signal generated by the circuit, which is equivalent to the heart of the microcontroller. To use the peripherals of the microcontroller, the corresponding clock must be turned on 驱动外设的本质是操作寄存器,而寄存器是由D触发器构成,而触发器需要时钟才能改写值,所以要想操作寄存器必须开启对应外设的时钟. For the CPU, it is assumed that the CPU executes an instruction (binary code) in one clock cycle. If the clock frequency is higher, and the clock is equal to 1/f as the reciprocal of the frequency, then the clock cycle is shorter and the CPU can execute more at the same time. More means, the CPU runs faster, and there will be an STM32 overclocking experiment at the back of the article to make the lights flash faster. (The principle of the experiment will be explained in detail later)

2. Why there is a clock tree
The main purpose of the STM32 clock system is to provide clocks for relatively independent peripheral modules, mainly to reduce the power consumption of the entire chip 所有外设时钟默认都是关闭状态(disable)当我们使用某个外设就要开启这个外设的时钟(enable). Different peripherals require different clock frequencies, so it is not necessary for all peripherals to be Using high-speed clocks is wasteful, and some peripherals cannot accept such a high frequency, which is why STM32 has four clock sources, which are compatible with peripherals of different speeds. The four clock sources of STM32 are: HSE, LSE , HSI, LSI

2. Clock tree

insert image description here
Let’s take a cursory look at the clock diagram first, followed by a detailed explanation of the clock source (emphasis), here is the atomic STM32f10RCT6mini board as an example

1. HSE clock

  • HSE: High Speed ​​External Clock signal, that is, a high-speed external clock.
  • Source: passive crystal oscillator (4-16M), usually 8M is used.
  • Function: It can be used as the input of the PLL phase-locked loop without frequency division or frequency division by 2 (frequency/2), and can also be directly used as the system clock without frequency division, and as the input of peripheral RTC clock by 128 frequency division
  • Control: The HSE crystal can be turned on and off by setting the HSEON bit in RCC_CR in the clock control register. The HSERDY bit in the clock control register RCC_CR is used to indicate whether the high-speed external oscillator is stable. At startup, the clock is not released until this bit is set to '1' by hardware.
    1. Source:
    insert image description here
    2. Function
    insert image description here
    3. Control
    insert image description here

2. HSI clock

  • HSI: High Speed ​​Internal Clock signal, high-speed internal clock.
  • Source: inside the chip, the size is 8M, when the HSE fails, the system clock will automatically switch to the HSI until the HSE starts successfully.
  • Function: It can be used as the system clock directly or as the PLL input after dividing by 2. The HSI RC oscillator provides the system clock without requiring any external components. It has a shorter start-up time than the HSE crystal oscillator. However, its clock frequency accuracy is poor even after calibration
  • Control: The HSIRDY bit in the Clock Control register is used to indicate whether the HSI RC oscillator is stable. During clock startup, the HSI RC output clock is not released until this bit is set to '1' by hardware. The HSI RC can be enabled and disabled by the HSION bit in the clock control register. If the HSE crystal oscillator fails, the HSI clock will be used as a backup clock source

1. Function
insert image description here
2. Control
insert image description here

3. LSE clock

  • LSE: low Speed ​​External Clock signal, low-speed external clock.
  • Source: Inside the chip, the LSE crystal is a 32.768kHz low speed external crystal or ceramic resonator. It provides a low-power and accurate clock source for the real-time clock or other timing functions.
  • Role: directly as RTC is the clock source
  • Control: The LSE crystal is turned on and off by the LSEON bit in the Backup Domain Control Register (RCC_BDCR). LSERDY in the Backup Domain Control Register (RCC_BDCR) indicates whether the LSE crystal oscillation is stable. During the startup phase, the LSE clock signal is not released until this bit is set to '1' by hardware.
    1. Function
    insert image description here
    2. Control
    insert image description here

4. LSI clock

  • LSI: low Speed ​​Internal Clock signal, low-speed internal clock.
  • Source: Internal chip, LSI RC acts as a low power clock source, it can keep running in shutdown and standby mode, LSI clock frequency is about 40kHz (between 30kHz and 60kHz).
  • Function: Provide clock for independent watchdog and automatic wake-up unit (RTC)
  • Control: The LSI RC can be enabled or disabled by the LSION bit in the Control/Status register (RCC_CSR). The LSIRDY bit in the Control/Status register (RCC_CSR) indicates whether the low-speed internal oscillator is stable. During the startup phase, the clock is not released until this bit is set to '1' by hardware.

1. Function
insert image description here
2. Control

insert image description here

5. Phase-locked loop clock PLLCLK

  • Phase Locked Loop Clock: PLLCLK
  • Source: Select HIS oscillator divided by 2 or HSE oscillator as the input clock to the PLL, and select the multiplier factor, which must be done before it is activated. Once the PLL is activated, these parameters cannot be changed.
  • Function: The internal PLL can be used to multiply the output clock of HSI RC or the output clock of HSE crystal (multiplied by 2~16 times), and it can be used as the system clock source after the multiplication becomes PLLCLK
  • Control: register RCC_CFGR: PLLXTPRE, PLLMUL, PLLSRC bits, register RCC_CR: PLLNO, PLLRDY see the following figure for details
  • Note: When the PLL clock source uses HIS/2, the maximum PLLMUL can only be 16. At this time, the maximum PLLCLK can only be 64M, which is less than the maximum clock recommended by ST, which is 72M. If the USB interface needs to be used in the application, the PLL must be set to output a 48 or 72MHz clock to provide the 48MHz USBCLK clock.

1. Function
这个图是重中之重
insert image description here

6. System clock SYSCLK

  • System clock: SYSCLK, up to 72M (officially recommended by ST)
  • Source: HSI, HSE, PLLCLK.
  • Control: CFGR: SW
  • Note: The usual configuration is SYSCLK=PLLCLK=72M.

1. Source: insert image description here
2. Control
insert image description here
通常的配置是SYSCLK=PLLCLK=72M,配置流程,这里也非常重要后面实验就按照这个过程写代码

insert image description here

7. HCLK clock

  • HCLK: AHB high-speed bus clock, the maximum speed is 72M.
  • Function: Provide clock for peripherals of AHB bus, provide clock for Cortex system timer (SysTick), and provide time for core (FCLK) .
  • Source: obtained by dividing the system clock, generally set HCLK=SYSCLK=72M
  • Control: CFGR:HPRE

1. Function:
insert image description here

2. Control
insert image description here

8. PCLK1 clock

  • PCLK1: APB1 low-speed bus clock, up to 36M.
  • Function: Provide clock for peripherals of APB1 bus. After the frequency is multiplied by 1 or 2, it provides the clock for the timers 2~7 of the APB1 bus, and the maximum is 72M.
  • Source: HCLK divided by frequency, general configuration PCLK1=HCLK/2=36M
  • Control: PPRE1 bit of RCC_CFGR Clock Configuration Register

1. Function
insert image description here
2. Control
insert image description here

9. PCLK2 clock

  • PCLK2: APB2 high-speed bus clock, up to 72M.
  • Function: Provide clock for peripherals of APB2 bus. Provide clock for timer 1 and 8 of APB2 bus, the maximum is 72M. The APB2 frequency divider also has an output for the ADC frequency divider, which is sent to the ADC module after frequency division.
  • Source: HCLK divided by frequency, general configuration PCLK1=HCLK=72M
  • Control: PPRE2 bit of RCC_CFGR Clock Configuration Register

1. Function
insert image description here
2. Control
insert image description here

10. RTC clock

  • RTC clock: Provide clock for the RTC peripherals inside the chip.
  • Source: HSE_RTC (HSE divided by frequency), LSE (provided by an external 32.768KHZ crystal), LSI (32KHZ).
  • Control: RCC Backup Domain Control Register RCC_BDCR: RTCSEL bit control

Independent watchdog clock: IWDGCLK, controlled by
insert image description here
LSI
insert image description here

Clock Security System (CSS)

insert image description here
Monitor the working state of the high-speed external clock HSE. If the HSE fails, the high-speed internal clock HSI will be automatically switched as the input of the system clock to ensure the normal operation of the system. Once the CSS is activated and the HSE clock fails, the CSS interrupt is generated and the NMI is automatically generated. The NMI will be
executed continuously until the CSS interrupt pending bit is cleared.

MCO clock output

  • MCO: microcontroller clockoutput, microcontroller clock output 引脚, multiplexed by PA8. You can output the clock signal for external use, or you can use an oscilloscope to detect the parameters of the clock signal (peak-to-peak value, frequency...)
  • Source: PLLCLK/2, HSE, HSI, SYSCLK
  • Control: CRGR: MCO
    insert image description here
    Here is the complete clock tree
    insert image description here

3. Explain the clock system clock configuration function

1. The first program executed by STM32 is powered on

When the STM32 microcontroller is powered on, the reset program in the startup file (written in assembly code) will be executed.
insert image description here
Execute the reset procedure
1. Call the SystemInit system initialization function to complete the configuration of the system clock (configured to 72MHZ)
2. Call the _main function to initialize the stack pointer, and then call the C library function main function to go to the C language world
so jump to C When the main function of the language is executed, the configuration of the system clock (SYSCLK) has been completed.

insert image description here

2.SystemInit system clock initialization function

Taking the chip model: STM32F10X_HD as an example,
insert image description here
the system clock is configured to the officially recommended 72MHZ .
Steps:
The 8MHz provided by the external crystal oscillator (HSE) is not divided by the PLLXTPRE frequency divider, input to PLLSRC, and then multiplied by 9 through the PLLMUL phase-locked loop to output the PLLCLK clock (72MHZ), and then switch the PLLCLK through the system clock switch SW. As the system clock (72MHZ). Then divide the frequency by 1 through the AHB prescaler to obtain the AHB bus clock (HCLK), and then divide the frequency by 2 and 1 through the APB1 and APB2 prescalers, respectively, to provide the APB1 (PCLK1) APB2 (PCLK2) bus. Clock, and then provide a clock
coordination diagram for the peripherals mounted on the APB1 and APB2 buses to understand:
insert image description here

insert image description here
insert image description here

Also, if you are not familiar with conditional compilation, you must read -> preprocessing instructions , otherwise you don't know how to call the function.

here comes the point

static void SetSysClockTo72(void)
{
    
    
  __IO uint32_t StartUpCounter = 0, HSEStatus = 0;
  
  /* SYSCLK, HCLK, PCLK2 and PCLK1 configuration ---------------------------*/    
  /* Enable HSE :使能 HSE  */
  RCC->CR |= ((uint32_t)RCC_CR_HSEON);
 
  /*  Wait till HSE is ready and if Time out is reached exit */
  //等待HSE就绪并做超时处理
  do
  {
    
    
    HSEStatus = RCC->CR & RCC_CR_HSERDY;
    StartUpCounter++;  
  } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));

  if ((RCC->CR & RCC_CR_HSERDY) != RESET)
  {
    
    
    HSEStatus = (uint32_t)0x01;
  }
  else
  {
    
    
    HSEStatus = (uint32_t)0x00;
  }  

  //启动成功执行下一步的代码
  if (HSEStatus == (uint32_t)0x01)
  {
    
    
    /*使能预取指 cpu在FLASH取代码*/
    FLASH->ACR |= FLASH_ACR_PRFTBE;

    /* Flash 2 wait state :设置成两个等待周期 */
    FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY);
    FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_2;    

 
    /* HCLK = SYSCLK =72M */
    RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;
      
    /* PCLK2 = HCLK =72M */
    RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1;
    
    /* PCLK1 = HCLK =36M */
    RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2; //二分频
    /*  锁相环配置: PLLCLK = HSE * 9 = 72 MHz */
    RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE |
                                        RCC_CFGR_PLLMULL));
    RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLMULL9);


    /* Enable PLL :使能PLL*/ 
    RCC->CR |= RCC_CR_PLLON;

    /* Wait till PLL is ready :等待PLL稳定*/
    while((RCC->CR & RCC_CR_PLLRDY) == 0)
    {
    
    
    }
    
    /* Select PLL as system clock source :选择PLL作为系统时钟*/
    RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
    RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL;    

    /* Wait till PLL is used as system clock source :等待PLLCLK切换为系统时钟*/
    while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x08)
    {
    
    
    }
  }
  else
  {
    
     /* If HSE fails to start-up, the application will have wrong clock 
         configuration. User can add here some code to deal with this error */
		 //如果HSE 启动失败,用户可以在这里添加处理错误的代码
  }
}

In the same way, fold some if statements and look at the overall framework of the function:
insert image description here
if the HSE starts successfully, execute the contents of the folded if statement.
insert image description here
Due to the limited space, it is really not good to analyze the register operations one by one. I have already jumped macros one by one and then Corresponding to the register, it is recommended to look at the manual one by one to see if it is really the corresponding bit of the operating register.

3. Turn on the peripheral clock

At this point, the system clock is configured, and the clocks of the bus AHB, APB1, and APB2 are also configured. The clocks of the peripherals mounted on these buses, whichever peripherals you want to use, turn on the clocks of
insert image description here
these registers. The bit corresponds to the peripheral clock enable bit mounted on the bus.

4. Write the system clock initialization function yourself to achieve overclocking

1. Function implementation

#include "rccclkconfig.h"

void HSE_System_Config( uint32_t RCC_PLLMul_x)
{
    
    
	
	ErrorStatus HSEStatus;
	/* 把RCC寄存器配置成复位值 */
	 RCC_DeInit();
	/* 使能SHE */
	RCC_HSEConfig(RCC_HSE_ON);
	HSEStatus=  RCC_WaitForHSEStartUp();
	
	/* 判断SHE启动是否成功 */
	if ( HSEStatus ==SUCCESS )
	{
    
    
		/*使能预取指 cpu在FLASH取代码*/
		FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
		/* 设置成两个等待周期 */
		FLASH_SetLatency(FLASH_Latency_2);
		
		/* HCLK = SYSCLK =72M */
    RCC_HCLKConfig(RCC_SYSCLK_Div1);
		
		 /* PCLK2 = HCLK =72M */
    RCC_PCLK1Config(RCC_HCLK_Div2);
		
		/* PCLK1 = HCLK =36M */
    RCC_PCLK2Config(RCC_HCLK_Div1);
		
		 /*  锁相环配置: PLLCLK = HSE * x(2-16) = 8*x MHz */
    RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_x);
		 /* 使能PLL*/
    RCC_PLLCmd(ENABLE);	
		 /* 等待PLL稳定 */
  while( RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);
		
		/* 选择pLL作为系统时钟 */
    RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
		 /* 等待PLLCLK切换为系统时钟 */
   while( RCC_GetSYSCLKSource() != 0x08) ;
		 
	}
	else
	{
    
    
		/* If HSE fails to start-up, the application will have wrong clock 
         configuration. User can add here some code to deal with this error */
	}
}

The code has detailed comments and is written with library functions, but it is basically the same as the previous register version, except that they are encapsulated into functions. The point to note here is that a RCC_DeInit() must be called before configuration; the function converts the RCC register Configured to reset value.

2. Realize overclocking to make LED lights flash faster

Principle: For the CPU, it is assumed that the CPU executes an instruction (binary code) in one clock cycle. If the clock frequency is higher, and the clock is equal to 1/f as the reciprocal of the frequency, then the clock cycle is shorter and the CPU can be at the same time. The more fingers are executed, the faster the CPU executes the code, the shorter the delay time, and the faster the light flashes.


#define SOFT_DELAY Delay(0x0FFFFF);

void Delay(__IO u32 nCount); 

int main(void)
{
    
    		
	HSE_System_Config( RCC_PLLMul_2);
	/* LED 端口初始化 */
	LED_GPIO_Config();	 

	while(1)
	{
    
    
      LED_G(NO);
      LED_R(OFF);
      Delay(0x0FFFFF);
      LED_G(OFF);
      LED_R(NO);
      Delay(0x0FFFFF);	
	}
}

void Delay(__IO uint32_t nCount)	 //简单的延时函数
{
    
    
	for(; nCount != 0; nCount--);
}

In order to have a more obvious experimental effect here, let the PLLMUL phase-locked loop perform 2 frequency multiplication and then output the PLLCLK clock (16MHZ), and then use the system clock switch SW to use the PLLCLK as the system clock (16MHZ).
insert image description here
Then let the PLLMUL phase-locked loop perform 16 multiplication and output the PLLCLK clock (128MHZ), and then use the PLLCLK as the system clock (128MHZ) through the system clock switching SW.
insert image description here

3. Experimental effect

PLLMUL phase-locked loop double frequency SYSCLK (16MHZ) experimental results:
Please add image description
PLLMUL phase-locked loop double frequency SYSCLK (128MHZ) experimental results:
Please add image description

Is it going to take off directly? It's very confusing. I won't upload a video.

5. Summary

All in all, the clock tree is very important and must be mastered! ! ! It is best to write a library function version of the system clock initialization function yourself. Well, this article is over. If this article is helpful to you, please like it! ! ! .

Guess you like

Origin blog.csdn.net/k666499436/article/details/124111203