STM32F4xx开发学习_RCC时钟树配置

2024-05-08 16:44

本文主要是介绍STM32F4xx开发学习_RCC时钟树配置,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

RCC(复位与时钟控制)

主要作用有两个,复位与时钟

复位

RCC_reset

1、系统复位

系统复位将所有寄存器设置为其复位值,通过以下事件触发

  • 外部复位,即NRST引脚低电平
  • 窗口看门狗计数结束条件,即窗口看门狗复位
  • 独立看门狗计数结束条件,即独立看门狗复位
  • 软件复位,判断RCC_CSR寄存器上的复位标志位
  • 低功耗管理复位,进入待机模式或停机模式

2、电源复位

电源复位将所有寄存器设置为其复位值除了备份域,通过以下事件触发

  • POR/PDR 复位信号或BOR复位信号
  • 退出待机模式

3、备份域复位

备份域复位将所有的RTC寄存器、RCC-BDCR寄存器、PWR_CSR寄存器BRE位设为其复位值,必须设置PWR_CR寄存器中的BDP位才能产生备份域复位。重置BKPSRAM的唯一方法是通过Flash接口请求将保护级别从1改为0。通过以下事件产生复位

  • 软件复位,通过RCC_BDCR寄存器中的BDRST位触发
  • V D D V_{DD} VDD V B A T V_{BAT} VBAT都断电

时钟

STM32系统时钟(SYSCLK)有三种时钟源

  • 高速内部时钟HSI
  • 高速外部时钟HSE
  • 主PLL时钟

有两种辅助时钟源

  • 低速内部时钟LSI(32KHz)
  • 低速外部时钟LSE(32.768KHz)

RCC时钟树
多个预分频器可用于配置多种时钟频率,AHB总线最大时钟频率为168MHz,APB2总线最大时钟频率为84MHz,APB1总线最大时钟频率为42MHz。定时器外设都在APB总线,定时器时钟频率有两种情况

  • 如果APB总线预分频系数为1,则定时器时钟频率与该总线时钟频率相等
  • 如果APB总线预分频系数不为1,则定时器时钟频率是该总线时钟频率两倍

1、HSE

高速外部时钟,可以由有源晶振无源晶振提供,频率从4-26MHZ不等。当使用有源晶振时,时钟从OSC_IN引脚进入, OSC_OUT引脚悬空,当选用无源晶振时,时钟从OSC_IN和OSC_OUT进入,并且要配谐振电容,尽可能靠经晶振引脚以减少输出失真和稳定启动事件。当HSE故障时,PLL也会关闭,系统时钟由HSI提供。

HSE/LSE时钟

2、HSI

高速内部时钟,由内部16MHz的RC振荡器产生。虽然无需外围电路且启动时间比HSE短,但是时钟频率不如HSE准确,制造工艺不同时钟频率也会不同,同时环境温度对齐也会有影响。系统复位后,HSI默认为系统时钟。

3、锁相环PLL

PLL的主要作用是对时钟进行倍频,然后把时钟输出到各个功能部件。STM32F4xx有两个PLL

  • 主PLL
    主PLL对HSE或HSI的时钟频率进行倍频,具有两种不同的时钟输出
    • 高速系统时钟,PLLCLK = HCLK = SYSCLK = 168MHz
    • USB OTG FS(48MHz)、随机模拟数生成器( ≤ 48 M H z \le 48MHz 48MHz)和SDIO( ≤ 48 M H z \le 48MHz 48MHz
  • 专用PLL
    为I2S接口实现高质量音频性能表现提供准确时钟频率

PLL只能在启动系统之前进行配置,即对M、N、P和Q进行配置。

4、LSE

LSE时钟由32.768KHz的晶振产生,主要用于RTC。

5、LSI

内部低速时钟,由内部32KHzRC振荡器产生。

6、时钟相关计算

HSE或HSI经过PLL时钟输入分频因子M( 2 ≤ P L L M ≤ 63 2 \le PLLM \le 63 2PLLM63)分频,进入压控振荡器(VCO),VCO输入频率范围应在 1 − 2 M H z 1-2MHz 12MHz内,VCO输入频率公式: V C O i n F = H S E 或 H S I P L L M VCO_{inF} = \frac {HSE或HSI}{PLLM} VCOinF=PLLMHSEHSI,这里板载HSE为8MHz,PLLM设置为8,则计算公式为: V C O i n F = 8 M H z 8 = 1 M H z VCO_{inF} = \frac {8MHz}{8} = 1MHz VCOinF=88MHz=1MHz
VCO输入频率 V C O i n F VCO_{inF} VCOinF经过VCO倍频因子N( 50 ≤ P L L N ≤ 432 50 \le PLLN \le 432 50PLLN432)倍频之后,成为VCO时钟输出,输出范围在 100 M H z ≤ V C O o u t F ≤ 432 M H z 100MHz \le VCO_{outF} \le 432MHz 100MHzVCOoutF432MHz内,VCO输出频率公式: V C O o u t F = V C O i n F × P L L N VCO_{outF} = VCO_{inF} \times PLLN VCOoutF=VCOinF×PLLN,这里设置PLLN为336,则计算公式为: V C O o u t F = V C O i n F × P L L N = 336 M H z VCO_{outF} = VCO_{inF} \times PLLN = 336MHz VCOoutF=VCOinF×PLLN=336MHz
VCO输出频率 V C O o u t F VCO_{outF} VCOoutF经过锁相环倍频因子P( P L L P = 2 , 4 , 6 o r 8 PLLP = 2, 4, 6 or 8 PLLP=2,4,6or8)倍频之后,产生不超过168MHz的锁相环输出频率 P L L C L K PLLCLK PLLCLK,这里设置PLLP为2,则计算公式为: P L L C L K f = V C O o u t F P L L P = 336 M H z 2 = 168 M H z PLLCLK_f = \frac {VCO_{outF}}{PLLP} = \frac {336MHz}{2} = 168MHz PLLCLKf=PLLPVCOoutF=2336MHz=168MHz
USB OTG FS/RNG/SDIO时钟分频因子Q( 2 ≤ P L L Q ≤ 15 2 \le PLLQ \le 15 2PLLQ15),USB OTG FS要求48MHz时钟,这里设置PLLQ为7即可。
分频因子R(F446才有,F407没有)。

7、总线时钟频率

  1. 高速APB总线(APB2),通过RCC_CFGR寄存器中的PPRE2[15:13]位进行配置预分频系数,不超过频率84MHz,这里设置2分频,即AHB总线频率168MHz的一半,PCLK2=HCLK/2=84MHz
  2. 低速APB总线(APB1),通过RCC_CFGR寄存器中的PPRE1[12:10]位进行配置预分频系数,不超过频率42MHz,这里设置4分频,即AHB总线频率168MHz的四分之一,PCLK1=HCLK/4=42MHz
  3. AHB总线,RCC_CFGR寄存器中的HPRE[7:4]位进行配置预分频系数,最低频率为25MHz,这里设置为1分频,即HCLK=SYSCLK=168MHz

设置系统时钟

system_stm32f4xx.c文件中给出了系统时钟函数,SystemInit(void)

/*** @brief  Setup the microcontroller system*         Initialize the Embedded Flash Interface, the PLL and update the *         SystemFrequency variable.* @param  None* @retval None*/
void SystemInit(void)
{/* FPU settings ------------------------------------------------------------*/#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2));  /* set CP10 and CP11 Full Access */#endif/* Reset the RCC clock configuration to the default reset state ------------*//* Set HSION bit */RCC->CR |= (uint32_t)0x00000001;//开启HSI/* Reset CFGR register */RCC->CFGR = 0x00000000;//RCC时钟配置寄存器复位/* Reset HSEON, CSSON and PLLON bits */RCC->CR &= (uint32_t)0xFEF6FFFF;//关闭PLL,CSS,关闭HSE/* Reset PLLCFGR register */RCC->PLLCFGR = 0x24003010;//复位PLL/* Reset HSEBYP bit */RCC->CR &= (uint32_t)0xFFFBFFFF;//复位HSE时钟旁路/* Disable all interrupts */RCC->CIR = 0x00000000;//失能所有中断#if defined(DATA_IN_ExtSRAM) || defined(DATA_IN_ExtSDRAM)SystemInit_ExtMemCtl(); 
#endif /* DATA_IN_ExtSRAM || DATA_IN_ExtSDRAM *//* Configure the System clock source, PLL Multiplier and Divider factors, AHB/APBx prescalers and Flash settings ----------------------------------*/SetSysClock();/* Configure the Vector Table location add offset address ------------------*/
#ifdef VECT_TAB_SRAMSCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */
#elseSCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */
#endif
}

SetSysClock(void)函数用于设置系统时钟,启动文件startup_stm32f40xxx.s会将SYSCLK将系统时钟初始化为168MHz,代码如下

/*** @brief  Configures the System clock source, PLL Multiplier and Divider factors, *         AHB/APBx prescalers and Flash settings* @Note   This function should be called only once the RCC clock configuration  *         is reset to the default reset state (done in SystemInit() function).   * @param  None* @retval None*/
static void SetSysClock(void)
{
#if defined(STM32F40_41xxx) || defined(STM32F427_437xx) || defined(STM32F429_439xx) || defined(STM32F401xx) || defined(STM32F412xG) || defined(STM32F446xx)|| defined(STM32F469_479xx)
/******************************************************************************/
/*            PLL (clocked by HSE) used as System clock source                */
/******************************************************************************/__IO uint32_t StartUpCounter = 0, HSEStatus = 0;/* 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){/* Select regulator voltage output Scale 1 mode */RCC->APB1ENR |= RCC_APB1ENR_PWREN;PWR->CR |= PWR_CR_VOS;/* HCLK = SYSCLK / 1*/RCC->CFGR |= RCC_CFGR_HPRE_DIV1;#if defined(STM32F40_41xxx) || defined(STM32F427_437xx) || defined(STM32F429_439xx) ||  defined(STM32F412xG) || defined(STM32F446xx) || defined(STM32F469_479xx)    /* PCLK2 = HCLK / 2*/RCC->CFGR |= RCC_CFGR_PPRE2_DIV2;/* PCLK1 = HCLK / 4*/RCC->CFGR |= RCC_CFGR_PPRE1_DIV4;
#endif /* STM32F40_41xxx || STM32F427_437x || STM32F429_439xx  || STM32F412xG || STM32F446xx || STM32F469_479xx */
#if defined(STM32F40_41xxx) || defined(STM32F427_437xx) || defined(STM32F429_439xx) || defined(STM32F401xx) || defined(STM32F469_479xx)    /* Configure the main PLL */RCC->PLLCFGR = PLL_M | (PLL_N << 6) | (((PLL_P >> 1) -1) << 16) |(RCC_PLLCFGR_PLLSRC_HSE) | (PLL_Q << 24);
#endif /* STM32F40_41xxx || STM32F401xx || STM32F427_437x || STM32F429_439xx || STM32F469_479xx *//* Enable the main PLL */RCC->CR |= RCC_CR_PLLON;/* Wait till the main PLL is ready */while((RCC->CR & RCC_CR_PLLRDY) == 0){}
#if defined(STM32F40_41xxx)  || defined(STM32F412xG)   /* Configure Flash prefetch, Instruction cache, Data cache and wait state */FLASH->ACR = FLASH_ACR_PRFTEN | FLASH_ACR_ICEN |FLASH_ACR_DCEN |FLASH_ACR_LATENCY_5WS;
#endif /* STM32F40_41xxx  || STM32F412xG *//* Select the main PLL as system clock source */RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));RCC->CFGR |= RCC_CFGR_SW_PLL;/* Wait till the main PLL is used as system clock source */while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS ) != RCC_CFGR_SWS_PLL);{}}else{ /* If HSE fails to start-up, the application will have wrong clockconfiguration. User can add here some code to deal with this error */}
#elif defined(STM32F410xx) || defined(STM32F411xE)
#endif /* STM32F40_41xxx || STM32F427_437xx || STM32F429_439xx || STM32F401xx || STM32F469_479xx */  
}

这篇关于STM32F4xx开发学习_RCC时钟树配置的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/970869

相关文章

Android 悬浮窗开发示例((动态权限请求 | 前台服务和通知 | 悬浮窗创建 )

《Android悬浮窗开发示例((动态权限请求|前台服务和通知|悬浮窗创建)》本文介绍了Android悬浮窗的实现效果,包括动态权限请求、前台服务和通知的使用,悬浮窗权限需要动态申请并引导... 目录一、悬浮窗 动态权限请求1、动态请求权限2、悬浮窗权限说明3、检查动态权限4、申请动态权限5、权限设置完毕后

Java深度学习库DJL实现Python的NumPy方式

《Java深度学习库DJL实现Python的NumPy方式》本文介绍了DJL库的背景和基本功能,包括NDArray的创建、数学运算、数据获取和设置等,同时,还展示了如何使用NDArray进行数据预处理... 目录1 NDArray 的背景介绍1.1 架构2 JavaDJL使用2.1 安装DJL2.2 基本操

SpringBoot+MyBatis-Flex配置ProxySQL的实现步骤

《SpringBoot+MyBatis-Flex配置ProxySQL的实现步骤》本文主要介绍了SpringBoot+MyBatis-Flex配置ProxySQL的实现步骤,文中通过示例代码介绍的非常详... 目录 目标 步骤 1:确保 ProxySQL 和 mysql 主从同步已正确配置ProxySQL 的

Spring Boot整合log4j2日志配置的详细教程

《SpringBoot整合log4j2日志配置的详细教程》:本文主要介绍SpringBoot项目中整合Log4j2日志框架的步骤和配置,包括常用日志框架的比较、配置参数介绍、Log4j2配置详解... 目录前言一、常用日志框架二、配置参数介绍1. 日志级别2. 输出形式3. 日志格式3.1 PatternL

配置springboot项目动静分离打包分离lib方式

《配置springboot项目动静分离打包分离lib方式》本文介绍了如何将SpringBoot工程中的静态资源和配置文件分离出来,以减少jar包大小,方便修改配置文件,通过在jar包同级目录创建co... 目录前言1、分离配置文件原理2、pom文件配置3、使用package命令打包4、总结前言默认情况下,

基于Python开发PPTX压缩工具

《基于Python开发PPTX压缩工具》在日常办公中,PPT文件往往因为图片过大而导致文件体积过大,不便于传输和存储,所以本文将使用Python开发一个PPTX压缩工具,需要的可以了解下... 目录引言全部代码环境准备代码结构代码实现运行结果引言在日常办公中,PPT文件往往因为图片过大而导致文件体积过大,

使用DeepSeek API 结合VSCode提升开发效率

《使用DeepSeekAPI结合VSCode提升开发效率》:本文主要介绍DeepSeekAPI与VisualStudioCode(VSCode)结合使用,以提升软件开发效率,具有一定的参考价值... 目录引言准备工作安装必要的 VSCode 扩展配置 DeepSeek API1. 创建 API 请求文件2.

VScode连接远程Linux服务器环境配置图文教程

《VScode连接远程Linux服务器环境配置图文教程》:本文主要介绍如何安装和配置VSCode,包括安装步骤、环境配置(如汉化包、远程SSH连接)、语言包安装(如C/C++插件)等,文中给出了详... 目录一、安装vscode二、环境配置1.中文汉化包2.安装remote-ssh,用于远程连接2.1安装2

Redis多种内存淘汰策略及配置技巧分享

《Redis多种内存淘汰策略及配置技巧分享》本文介绍了Redis内存满时的淘汰机制,包括内存淘汰机制的概念,Redis提供的8种淘汰策略(如noeviction、volatile-lru等)及其适用场... 目录前言一、什么是 Redis 的内存淘汰机制?二、Redis 内存淘汰策略1. pythonnoe

windos server2022的配置故障转移服务的图文教程

《windosserver2022的配置故障转移服务的图文教程》本文主要介绍了windosserver2022的配置故障转移服务的图文教程,以确保服务和应用程序的连续性和可用性,文中通过图文介绍的非... 目录准备环境:步骤故障转移群集是 Windows Server 2022 中提供的一种功能,用于在多个