STM32F429–RCC时钟树简介
- RCC全称:reset clock config ,复位和时钟控制,在中文参考手册的第六章
- 系统时钟: SYSCLK,首选PPL为系统时钟,可达180MHZ
- 时钟树 :单片机所有的时钟
学前概念须知:
STM32F429有5条总线 越高时钟越快由低到高分别是 :
APB1 -->APB2–>AHB1–>AHB2–>AHB3
-
HSE: 高速的外部时钟,板子采用无源晶振,设置为25M,精度较高,一般配置为这个。
-
HSI: 高速的内部时钟,为16M,当HSE故障时,自动切换到HSI,直到HSE启动.
-
PLLCLK:锁相环时钟 HSE->PLL->倍频到180M M/N/P
系统时钟:来源 HSI HSE PLLCLK 控制RCC_CFGR时钟配置寄存器的SW位 配置为10PLLCLK
-
HCLK:【 AHB高速总线时钟】,最高180M,为AHB总线外设提供 [important]
-
AHB: advanced high-performance bus 【高性能总线】
-
FCLK:free clock 内核CPU自由时钟
-
RTC: real time clock,实时时钟,为芯片内部的RTC提供时钟,具体看功能框图
下面都是由低到高速,对应5条总线的时钟 ,后面是分频因子
- PCLK1: 为APB1总线提供45M时钟,APB1总线定时器2倍频后90M时钟 RCC_CFGR寄存器配置,PPRE1位
- PCLK2: 为APB2总线提供90M时钟,APB2总线定时器2倍频后180M时钟 RCC_CFGR寄存器配置,PPRE2位
- PPRE2: APB高速预分频器
- PPRE1: APB地速预分频器
- APB1一般设置为45M , APB2一般设置为 90M
STM32F429时钟树功能框图
说明:
1–6部分为主系统时钟,A~F为外设和其他时钟
图中最高为168MHZ有误,应改为180MHZ
系统时钟配置流程:
static void SetSysClock(void)
选择HSE打开,默认25M -->
进入锁相环/M=25 ,最终为1M–>
设置倍频因子xN = 360M,VCO默认1 最终为360M–>
/ P设置为2 最终360/2=180M–>
选择PLLCLK作为系统时钟,不选HSI/HSE–>
设置1倍分频,得HCLK 360M–>
设置倍频因子为8,360/8=45M,最后得到APB1 45MHZ
设置倍频因子为8,360/4=90M,最后得到APB2 90MHZ
其他外设的时钟需要用到的时候再进行配置,这里不作说明。
总结:
先配置好HSI/HSEPLL振荡器作为PLL时钟源,并配置分频系数M/N/P/Q
A,B,C,D,F时钟在需要的时候才需要配置。
可通过MCO时钟输出来检测自己配置的PLLCLK在示波器显示,来判断是否成功配置为180MHZ。
程序部分
1-使能HSE,并等待HSE稳定
2-配置 AHB APB2 APB1 总线的预分频因子
3-配置 PLL的各种分频因子,并使能PLL
4-选择系统时钟来源
想要配置自己想要的时钟,可以直接修改提供的SetSysClock函数,不过为了保证库函数的完整性,我们可以通过固件库来自己实现一个,一般不选用HSI,精确度没有HSE的高。下面程序采用条件编译的方式,#if 0#else #endif 部分是从系统自带的时钟配置函数裁剪下来的部分。
bsp_rccclkconfig.c
#include "bsp_rccclkconfig.h"#if 0
static void SetSysClock(void)
{__IO uint32_t StartUpCounter = 0, HSEStatus = 0; RCC->CR |= ((uint32_t)RCC_CR_HSEON);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){
RCC->APB1ENR |= RCC_APB1ENR_PWREN;PWR->CR |= PWR_CR_VOS;
RCC->CFGR |&#61; RCC_CFGR_HPRE_DIV1; RCC->CFGR |&#61; RCC_CFGR_PPRE2_DIV2; RCC->CFGR |&#61; RCC_CFGR_PPRE1_DIV4; RCC->PLLCFGR &#61; PLL_M | (PLL_N << 6) | (((PLL_P >> 1) -1) << 16) |(RCC_PLLCFGR_PLLSRC_HSE) | (PLL_Q << 24);RCC->CR |&#61; RCC_CR_PLLON;while((RCC->CR & RCC_CR_PLLRDY) &#61;&#61; 0){} PWR->CR |&#61; PWR_CR_ODEN;while((PWR->CSR & PWR_CSR_ODRDY) &#61;&#61; 0){}PWR->CR |&#61; PWR_CR_ODSWEN;while((PWR->CSR & PWR_CSR_ODSWRDY) &#61;&#61; 0){} FLASH->ACR &#61; FLASH_ACR_PRFTEN |FLASH_ACR_ICEN |FLASH_ACR_DCEN |FLASH_ACR_LATENCY_5WS;RCC->CFGR &&#61; (uint32_t)((uint32_t)~(RCC_CFGR_SW));RCC->CFGR |&#61; RCC_CFGR_SW_PLL;while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS ) !&#61; RCC_CFGR_SWS_PLL);{}}else{ }
}#endif取值范围&#xff1a;
void HSE_SetSysClk(uint32_t m,uint32_t n,uint32_t p,uint32_t q)
{__IO uint32_t HSEStartUpStatus &#61; 0;RCC_HSEConfig(RCC_HSE_ON); HSEStartUpStatus &#61; RCC_WaitForHSEStartUp();if( HSEStartUpStatus &#61;&#61; SUCCESS ){RCC->APB1ENR |&#61; RCC_APB1ENR_PWREN;PWR->CR |&#61; PWR_CR_VOS;RCC_HCLKConfig(RCC_SYSCLK_Div1);RCC_PCLK2Config(RCC_HCLK_Div2);RCC_PCLK1Config(RCC_HCLK_Div4);RCC_PLLConfig(RCC_PLLSource_HSE, m, n, p, q);RCC_PLLCmd(ENABLE);while ( ( RCC_GetFlagStatus(RCC_FLAG_PLLRDY) ) &#61;&#61; RESET ){}PWR->CR |&#61; PWR_CR_ODEN;while((PWR->CSR & PWR_CSR_ODRDY) &#61;&#61; 0){}PWR->CR |&#61; PWR_CR_ODSWEN;while((PWR->CSR & PWR_CSR_ODSWRDY) &#61;&#61; 0){}FLASH->ACR &#61; FLASH_ACR_PRFTEN |FLASH_ACR_ICEN |FLASH_ACR_DCEN |FLASH_ACR_LATENCY_5WS;RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);while ( ( RCC_GetSYSCLKSource() ) !&#61; 0X08 ){} }else{ }
}
void MCO1_GPIO_Config(void)
{GPIO_InitTypeDef GPIO_InitStructure;RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);GPIO_InitStructure.GPIO_Pin &#61; GPIO_Pin_8;GPIO_InitStructure.GPIO_Speed &#61; GPIO_Speed_100MHz;GPIO_InitStructure.GPIO_Mode &#61; GPIO_Mode_AF;GPIO_InitStructure.GPIO_OType &#61; GPIO_OType_PP;GPIO_InitStructure.GPIO_PuPd &#61; GPIO_PuPd_UP; GPIO_Init(GPIOA, &GPIO_InitStructure);
}
void MCO2_GPIO_Config(void)
{GPIO_InitTypeDef GPIO_InitStructure;RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);GPIO_InitStructure.GPIO_Pin &#61; GPIO_Pin_9;GPIO_InitStructure.GPIO_Speed &#61; GPIO_Speed_100MHz;GPIO_InitStructure.GPIO_Mode &#61; GPIO_Mode_AF;GPIO_InitStructure.GPIO_OType &#61; GPIO_OType_PP;GPIO_InitStructure.GPIO_PuPd &#61; GPIO_PuPd_UP; GPIO_Init(GPIOC, &GPIO_InitStructure);
}
bsp_rccclkconfig.h
#ifndef __BSP_RCCCLKCONFIG_H
#define __BSP_RCCCLKCONFIG_H
#include "stm32f4xx_rcc.h"
void HSE_SetSysClk(uint32_t m,uint32_t n,uint32_t p,uint32_t q);
#endif
main.c
#include "stm32f4xx.h"
#include "bsp_rccclkconfig.h"
int main(void)
{
HSE_SetSysClk(25,432,2,9); RCC_MCO1Config(RCC_MCO1Source_PLLCLK, RCC_MCO1Div_1);while (1);
}