STM32~配置时钟频率[一文带你解决STM32主频配置],GitHub标星3.2K

  1. HSI内部8MHz的RC振荡器的误差在1%左右,内部RC振荡器的精度通常比用HSE(外部晶振)要差上十倍以上。

  2. 内部RC频率受温度影响比较大,如果省电Sleep模式下内部RC会停止工作。

1 . 时钟系统

在STM32中,有五个时钟源,为HSI、HSE、LSI、LSE、PLL。

  1. HSI是高速内部时钟,RC振荡器,频率为8MHz。

  2. HSE是高速外部时钟,可接石英/陶瓷谐振器,或者接外部时钟源,频率范围为4MHz~16MHz。

  3. LSI是低速内部时钟,RC振荡器,频率为40kHz。

  4. LSE是低速外部时钟,接频率为32.768kHz的石英晶体。

  5. PLL为锁相环倍频输出,其时钟输入源可选择为HSI/2、HSE或者HSE/2。倍频可选择为2~16倍,但是其输出频率最大不得超过72MHz。

STM32F10xx时钟系统  用户可通过多个预分频器配置AHB总线、高速APB2总线和低速APB1总线的频率。AHB和APB2域的最大频率是72MHZ。APB1域的最大允许频率是36MHZ。SDIO接口的时钟频STM32~配置时钟频率[一文带你解决STM32主频配置],GitHub标星3.2K_第1张图片
率固定为HCLK/2。

40kHz的LSI供独立看门狗IWDG使用,另外它还可以被选择为实时时钟RTC的时钟源。另外,实时时钟RTC的时钟源还可以选择LSE,或者是HSE的128分频。RTC的时钟源通过RTCSEL[1:0]来选择。

STM32中有一个全速功能的USB模块,其串行接口引擎需要一个频率为48MHz的时钟源。该时钟源只能从PLL输出端获取,可以选择为1.5分频或者1分频,也就是,当需要使用USB模块时,PLL必须使能,并且时钟频率配置为48MHz或72MHz。

另外,STM32还可以选择一个PLL输出的2分频、HSI、HSE、或者系统时钟SYSCLK输出到MCO脚(PA8)上。系统时钟SYSCLK,是供STM32中绝大部分部件工作的时钟源,它可选择为PLL输出、HSI或者HSE,(一般程序中采用PLL倍频到72Mhz)在选择时钟源前注意要判断目标时钟源是否已经稳定振荡。Max=72MHz,它分为2路,1路送给I2S2、I2S3使用的I2S2CLK,I2S3CLK;另外1路通过AHB分频器分频(1/2/4/8/16/64/128/256/512)分频后送给以下8大模块使用:

  1. 送给SDIO使用的SDIOCLK时钟。

  2. 送给FSMC使用的FSMCCLK时钟。

  3. 送给AHB总线、内核、内存和DMA使用的HCLK时钟。

  4. 通过8分频后送给Cortex的系统定时器时钟(SysTick)。

  5. 直接送给Cortex的空闲运行时钟FCLK。

  6. 送给APB1分频器。APB1分频器可选择1、2、4、8、16分频,其输出一路供APB1外设使用(PCLK1,最大频率36MHz),另一路送给定时器(Timer2-7)2、3、4倍频器使用。该倍频器可选择1或者2倍频,时钟输出供定时器2、3、4、5、6、7使用。

  7. 送给APB2分频器。APB2分频器可选择1、2、4、8、16分频,其输出一路供APB2外设使用(PCLK2,最大频率72MHz),另一路送给定时器(Timer1、Timer8)1、2倍频器使用。该倍频器可选择1或者2倍频,时钟输出供定时器1和定时器8使用。另外,APB2分频器还有一路输出供ADC分频器使用,分频后得到ADCCLK时钟送给ADC模块使用。ADC分频器可选择为2、4、6、8分频。

  8. 2分频后送给SDIO AHB接口使用(HCLK/2)。

详细参考:

  • STM32时钟系统学习

  • STM32的时钟树深入详解以及RCC配置

2 . 外部晶振作为时钟源

接下来,解决使用12M外部晶振时,如何配置作为系统时钟源。

第一步,修改stm32f10x.h中的HSE_VALUE为12000000

/**

  • @brief In the following line adjust the value of External High Speed oscillator (HSE)

used in your application

Tip: To avoid modifying this file each time you need to use different HSE, you

can define the HSE value in your toolchain compiler preprocessor.

*/

#if !defined HSE_VALUE

#ifdef STM32F10X_CL

#define HSE_VALUE ((uint32_t)25000000) /*!< Value of the External oscillator in Hz */

#else

#define HSE_VALUE ((uint32_t)12000000) /*!< Value of the External oscillator in Hz */

#endif /* STM32F10X_CL */

#endif /* HSE_VALUE */

第二步,修改system_stm32f10x.c中的时钟配置,先找到void SystemInit(void)—》SetSysClock()—》SetSysClockTo72(),将9倍频改为6倍频,12*6=72MHz

/**

  • @brief Sets System clock frequency to 72MHz and configure HCLK, PCLK2

  •     and PCLK1 prescalers. 
    
  • @note This function should be used only after reset.

  • @param None

  • @retval None

*/

static void SetSysClockTo72(void)

{

__IO uint32_t StartUpCounter = 0, HSEStatus = 0;

/* SYSCLK, HCLK, PCLK2 and PCLK1 configuration ---------------------------*/

/* Enable HSE */

RCC->CR |= ((uint32_t)RCC_CR_HSEON);

/* Wait till HSE is ready and if Time out is reached exit */

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)

{

/* Enable Prefetch Buffer */

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 */

RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;

/* PCLK2 = HCLK */

RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1;

/* PCLK1 = HCLK */

RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2;

#ifdef STM32F10X_CL

// …

#else
uint32_t)RCC_CFGR_HPRE_DIV1;

/* PCLK2 = HCLK */

RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1;

/* PCLK1 = HCLK */

RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2;

#ifdef STM32F10X_CL

// …

#else

你可能感兴趣的:(程序员,架构,移动开发,android)