STM32F1 clock tree

STM32F1 clock tree

Reference: "[Wildfire®] STM32—F103 Guide with Zero Dead Ends"
Insert picture description here

Clock source

  1. HSI: High-speed internal clock, RC oscillator, frequency is 8MHz
  2. HSE: High-speed external clock, which can be connected to a quartz/ceramic resonator or an external clock source, the frequency range is 4MHz~16MHz
  3. LSI: low-speed internal clock, RC oscillator, frequency 40kHz
  4. LSE: Low-speed external clock, connected to a quartz crystal with a frequency of 32.768kHz
  • LSI can be used to drive independent watchdogs and drive RTC through program selection. RTC is used to automatically wake up the system from shutdown/standby mode. LSE can also be used to drive RTC by program selection.

  • Internal means that the chip has been integrated, and external means that it needs to be connected when the PCB is designed

  • Phase-locked loop: This thing can amplify the input frequency and then output, for example, input 1MHz, set the multiplier to 3 times, and finally output a 3MHz signal. STM32's phase-locked loop frequency multiplication output, the clock input source can be selected as HSI/2, HSE or HSE/2. The multiplication frequency can be selected from 2 to 16 times, but the maximum output frequency should not exceed 72MHz.

Clock configuration

main

SYSCLK: system clock
HCLK: AHB bus clock
PCLK2: APB2 bus clock
PCLK1: APB1 bus clock

The standard configuration of library functions: PCLK2 = HCLK = SYSCLK = PLLCLK = 72M, PCLK1 = HCLK/2 = 36M
The peripherals equipped with APB1 and APB2 are shown in the following figure:

Insert picture description here

other

USB clock The
USB clock is obtained from PLLCLK through the USB prescaler. The frequency division factor can be: [1, 1.5], specifically configured by bit 22: USBPRE of the clock configuration register CFGR. The USB clock is up to 48M. According to the frequency division factor, PLLCLK can only be 48M or 72M. Generally we set PLLCLK=72M and USBCLK=48M. USB has relatively high requirements for clock, so PLLCLK can only be obtained by HSE multiplication, and HSI multiplication cannot be used.

Cortex system clock The
Cortex system clock is obtained by dividing the frequency of HCLK by 8 and is equal to 9M. The Cortex system clock is used to drive the core system timer SysTick. SysTick is generally used for the clock tick of the operating system and can also be used for ordinary timing.

ADC clock
ADC clock is obtained by PCLK2 through ADC prescaler. The frequency division factor can be [2,4,6,8], which is specifically determined by bits 15-14 of the clock configuration register CFGR: ADCPRE[1:0]. It is strange how there is no divide by 1. The ADC clock can only be up to 14M. If the sampling period is set to the shortest 1.5 cycles, the ADC conversion time can reach the shortest 1us. If you really want to achieve the shortest conversion time of 1us, then the ADC clock must be 14M, and the reverse PCLK2 clock can only be: 28M, 56M, 84M, 112M, since the maximum PCLK2 is 72M, only 28M and 56M can be used.

RTC clock and independent watchdog clock
RTC clock can be obtained by dividing the frequency of HSE/128, or it can be provided by low-speed external clock signal LSE, the frequency is 32.768KHZ, or it can be provided by low-speed internal clock signal HSI, which clock to choose is controlled by the backup domain control register Bits 9-8 of BDCR: RTCSEL[1:0] configuration. The clock of the independent watchdog is provided by LSI, and can only be provided by LSI, LSI is a low-speed internal clock signal, the frequency is directly ranging from 30 to 60KHZ, generally 40KHZ.

MCO clock output
MCO is the abbreviation of microcontroller clock output. It is the microcontroller clock output pin. It is multiplexed by PA8 in the STM32 F1 series. The main function is to provide an external clock, which is equivalent to an active crystal oscillator. The clock source of MCO can be: PLLCLK/2, HSI, HSE, SYSCLK, the specific selection is determined by bits 26-24 of the clock configuration register CFGR: MCO[2:0]. In addition to providing external clocks, we can also use an oscilloscope to monitor the clock output of the MCO pin to verify whether our system clock configuration is correct.

Setting code based on standard library

Using the standard library template project, when the system is started, statup_stm32f10x_hd.s has already called the SystemInit() function to initialize the system clock to 72MHZ, and SystemInit() is defined in the library file: system_stm32f10x.c. Then enter the main function.

If we want to set the system clock lower or overclock, we can modify the underlying library file, that is, modify the SystemInit() function. But in order to maintain the integrity of the library, you can write a clock initialization function to reconfigure the system clock when you enter the main function after starting in accordance with the standard library method.

The HSI setting system clock function is the same in principle as the HSE setting system clock function. One difference is that HSI must be divided by 2 before it can be used as the clock source of the PLL. Therefore, when using HSI, the maximum system clock SYSCLK can only be It is HSI/2 16=4 16=64MHZ.

 void HSE_SetSysClock(uint32_t pllmul)
{
    volatile uint32_t StartUpCounter = 0, HSEStartUpStatus = 0;
    RCC_DeInit();         //重设RCC寄存器为缺省值
    RCC_HSEConfig(RCC_HSE_ON);   //使能HSE
    
    do
  	{
    HSEStartUpStatus = RCC_WaitForHSEStartUp();
    StartUpCounter++;  
  	} while((HSEStartUpStatus == 0) && (StartUpCounter != 9));//等待 HSE 启动稳定
     
    if ( RCC_WaitForHSEStartUp() != 0)  //等待使能成功
  	{    	
//-----------------------------------------------------------------//
// 这两句是操作 FLASH 闪存用到的,如果不操作 FLASH,这两个注释掉也没影响
// 使能 FLASH 预存取缓冲区
	FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
// SYSCLK 周期与闪存访问时间的比例设置,这里统一设置成 2
// 设置成 2 的时候,SYSCLK 低于 48M 也可以工作,如果设置成 0 或者 1 的时候,
// 如果配置的 SYSCLK 超出了范围的话,则会进入硬件错误,程序就死了
// 0:0 < SYSCLK <= 24M
// 1:24< SYSCLK <= 48M
// 2:48< SYSCLK <= 72M
	FLASH_SetLatency(FLASH_Latency_2);
//-----------------------------------------------------------------//
     
    // AHB预分频因子设置为1分频,HCLK = SYSCLK 
    RCC_HCLKConfig(RCC_SYSCLK_Div1); 
    // APB2预分频因子设置为1分频,PCLK2 = HCLK
    RCC_PCLK2Config(RCC_HCLK_Div1); 
    // APB1预分频因子设置为1分频,PCLK1 = HCLK/2 
    RCC_PCLK1Config(RCC_HCLK_Div2);

//-----------------设置各种频率主要就是在这里设置-------------------//
    // 设置PLL时钟来源为HSE,设置PLL倍频因子
     // PLLCLK = 8MHz * pllmul
	RCC_PLLConfig(RCC_PLLSource_HSE_Div1, pllmul);
//------------------------------------------------------------------//

    // 开启PLL 
    RCC_PLLCmd(ENABLE);
    // 等待 PLL稳定
    while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);
    RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
    // 读取时钟切换状态位,确保PLLCLK被选为系统时钟
    while (RCC_GetSYSCLKSource() != 0x08);
       
   }
    else
    {
       // 当HSE开启失败或者故障的时候,单片机会自动把HSI设置为系统时钟,HSI是内部的高速时钟,8MHZ
       // 如果HSE开启失败,可在这里添加出错的代码处理
    }
    
}

MCO configuration

/*
 * 初始化MCO引脚PA8
 * 在F1系列中MCO引脚只有一个,即PA8,在F4系列中,MCO引脚会有两个
 */
void MCO_GPIO_Config(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	// 开启GPIOA的时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	
	// 选择GPIO8引脚
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
	
	//设置为复用功能推挽输出
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	
	//设置IO的翻转速率为50M
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	
	// 初始化GPIOA8
  GPIO_Init(GPIOA, &GPIO_InitStructure);
}

int main(void)
{	
	
	HSE_SetSysClock(RCC_PLLMul_9);
	MCO_GPIO_Config();// MCO 引脚初始化
		
	RCC_MCOConfig(RCC_MCO_SYSCLK);		     // 72M  
	
	while (1)
	{
		
	}

}

Guess you like

Origin blog.csdn.net/lblmlms/article/details/109165346