热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

STM32F429RCC时钟树

STM32F429–RCC时钟树简介RCC全称:resetclockconfig,复位和时钟控制,在中文参考手册的第六章系统时钟

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;/*-------------------------1-使能HSE,并等待HSE稳定----------------------------------------*/ /* 使能 HSE */RCC->CR |= ((uint32_t)RCC_CR_HSEON);/* 等待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;}/* HSE启动成功 */if (HSEStatus == (uint32_t)0x01){
/*----------------------------------------------------------------------------------------*//* 选择电压调节器输出为模式1 *//* 使能电源接口时钟 */RCC->APB1ENR |= RCC_APB1ENR_PWREN;PWR->CR |= PWR_CR_VOS;
/*----------------------------2-配置 AHB APB2 APB1 总线的预分频因子-----------------------*//* HCLK &#61; SYSCLK / 1*/RCC->CFGR |&#61; RCC_CFGR_HPRE_DIV1; /* PCLK2 &#61; HCLK / 2*/RCC->CFGR |&#61; RCC_CFGR_PPRE2_DIV2; /* PCLK1 &#61; HCLK / 4*/RCC->CFGR |&#61; RCC_CFGR_PPRE1_DIV4;/*----------------------------3-配置 PLL的各种分频因子&#xff0c;并使能PLL-----------------------*/ /* 配置 主 PLL */RCC->PLLCFGR &#61; PLL_M | (PLL_N << 6) | (((PLL_P >> 1) -1) << 16) |(RCC_PLLCFGR_PLLSRC_HSE) | (PLL_Q << 24);/* 使能 PLL */RCC->CR |&#61; RCC_CR_PLLON;/* 等待PLL启动稳定 */while((RCC->CR & RCC_CR_PLLRDY) &#61;&#61; 0){} /*----------------------------------------------------------------------------------------*//* 打开OVER-Drive模式&#xff0c;为的是达到更高的频率 */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 预取指, 指令缓存, 数据缓存 和等待周期 */FLASH->ACR &#61; FLASH_ACR_PRFTEN |FLASH_ACR_ICEN |FLASH_ACR_DCEN |FLASH_ACR_LATENCY_5WS;/*----------------------------4-选择系统时钟来源-----------------------------------------*//* 选择主锁相环时钟作为系统时钟 */RCC->CFGR &&#61; (uint32_t)((uint32_t)~(RCC_CFGR_SW));RCC->CFGR |&#61; RCC_CFGR_SW_PLL;/* 等待PLLCLH切换称系统时钟 */while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS ) !&#61; RCC_CFGR_SWS_PLL);{}}else{ /* HSE启动失败后&#xff0c;用户纠错的代码 */}
}#endif取值范围&#xff1a;
// m : 2~63
// n :192~432
// p &#xff1a;2、4、6、8
// q &#xff1a;2~15
// SYSCLK &#61; (HSE/m) * n /p &#61; 25/25 * 432 / 2 &#61; 216M
// HSE_SetSysClk(25,432,2,7)
void HSE_SetSysClk(uint32_t m,uint32_t n,uint32_t p,uint32_t q)
{__IO uint32_t HSEStartUpStatus &#61; 0;/* 使能HSE 并等待HSE稳定*/RCC_HSEConfig(RCC_HSE_ON); HSEStartUpStatus &#61; RCC_WaitForHSEStartUp();if( HSEStartUpStatus &#61;&#61; SUCCESS ){/* 选择电压调节器输出为模式1 *//* 使能电源接口时钟 */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 ){}/* 打开OVER-Drive模式&#xff0c;为的是达到更高的频率 */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 预取指, 指令缓存, 数据缓存 和等待周期 */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{ /* HSE启动识别&#xff0c;用户在这里添加纠错代码 */ }
}/*
*以下部分是配置MCO引脚输出的配置函数
*/

// MCO1 PA8 GPIO 初始化
void MCO1_GPIO_Config(void)
{GPIO_InitTypeDef GPIO_InitStructure;RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);// MCO1 GPIO 配置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);
}// MCO2 PC9 GPIO 初始化
void MCO2_GPIO_Config(void)
{GPIO_InitTypeDef GPIO_InitStructure;RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);// MCO2 GPIO 配置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 /*__BSP_RCCCLKCONFIG_H*/

main.c

#include "stm32f4xx.h"
#include "bsp_rccclkconfig.h"
int main(void)
{
// 程序来到main函数之前&#xff0c;启动文件已经调用SystemInit()函数把系统时钟初始化成180MHZ
// SystemInit()在system_stm32f4xx.c中定义,如果想修改系统时钟&#xff0c;可自行编写程序修改
// 重新设置系统时钟&#xff0c;这时候可以选择使用HSE还是HSI /* 把系统时钟初始化为216M */HSE_SetSysClk(25,432,2,9); // MCO1 输出PLLCLK RCC_MCO1Config(RCC_MCO1Source_PLLCLK, RCC_MCO1Div_1);while (1);
}


推荐阅读
  • 我正在使用 Ruby on Rails 构建个人网站。总体而言,RoR 是一个非常出色的工具,它提供了丰富的功能和灵活性,使得创建自定义页面变得既高效又便捷。通过利用其强大的框架和模块化设计,我可以轻松实现复杂的功能,同时保持代码的整洁和可维护性。此外,Rails 的社区支持也非常强大,为开发过程中遇到的问题提供了丰富的资源和解决方案。 ... [详细]
  • Spring Boot 实战(一):基础的CRUD操作详解
    在《Spring Boot 实战(一)》中,详细介绍了基础的CRUD操作,涵盖创建、读取、更新和删除等核心功能,适合初学者快速掌握Spring Boot框架的应用开发技巧。 ... [详细]
  • 在《PHP应用性能优化实战指南:从理论到实践的全面解析》一文中,作者分享了一次实际的PHP应用优化经验。文章回顾了先前进行的一次优化项目,指出即使系统运行时间较长后出现的各种问题和性能瓶颈,通过采用一些通用的优化策略仍然能够有效解决。文中不仅详细阐述了优化的具体步骤和方法,还结合实例分析了优化前后的性能对比,为读者提供了宝贵的参考和借鉴。 ... [详细]
  • 本文首先对信息漏洞的基础知识进行了概述,重点介绍了几种常见的信息泄露途径。具体包括目录遍历、PHPINFO信息泄露以及备份文件的不当下载。其中,备份文件下载涉及网站源代码、`.bak`文件、Vim缓存文件和`DS_Store`文件等。目录遍历漏洞的详细分析为后续深入研究奠定了基础。 ... [详细]
  • 从无到有,构建个人专属的操作系统解决方案
    操作系统(OS)被誉为程序员的三大浪漫之一,常被比喻为计算机的灵魂、大脑、内核和基石,其重要性不言而喻。本文将详细介绍如何从零开始构建个人专属的操作系统解决方案,涵盖从需求分析到系统设计、开发与测试的全过程,帮助读者深入理解操作系统的本质与实现方法。 ... [详细]
  • 在Spring Boot项目中,通过YAML配置文件为静态变量设置值的方法与实践涉及以下几个步骤:首先,创建一个新的配置类。需要注意的是,自动生成的setter方法默认是非静态的,因此需要手动将其修改为静态方法,以确保静态变量能够正确初始化。此外,建议使用`@Value`注解或`@ConfigurationProperties`注解来注入配置属性,以提高代码的可读性和维护性。 ... [详细]
  • 本文深入探讨了 MXOTDLL.dll 在 C# 环境中的应用与优化策略。针对近期公司从某生物技术供应商采购的指纹识别设备,该设备提供的 DLL 文件是用 C 语言编写的。为了更好地集成到现有的 C# 系统中,我们对原生的 C 语言 DLL 进行了封装,并利用 C# 的互操作性功能实现了高效调用。此外,文章还详细分析了在实际应用中可能遇到的性能瓶颈,并提出了一系列优化措施,以确保系统的稳定性和高效运行。 ... [详细]
  • 本题库精选了Java核心知识点的练习题,旨在帮助学习者巩固和检验对Java理论基础的掌握。其中,选择题部分涵盖了访问控制权限等关键概念,例如,Java语言中仅允许子类或同一包内的类访问的访问权限为protected。此外,题库还包括其他重要知识点,如异常处理、多线程、集合框架等,全面覆盖Java编程的核心内容。 ... [详细]
  • 本文详细探讨了C语言中`extern`关键字的简易编译方法,并深入解析了预编译、`static`和`extern`的综合应用。通过具体的代码示例,介绍了如何在不同的文件之间共享变量和函数声明,以及这些关键字在编译过程中的作用和影响。文章还讨论了预编译过程中宏定义的使用,为开发者提供了实用的编程技巧和最佳实践。 ... [详细]
  • 进程(Process)是指计算机中程序对特定数据集的一次运行活动,是系统资源分配与调度的核心单元,构成了操作系统架构的基础。在早期以进程为中心的计算机体系结构中,进程被视为程序的执行实例,其状态和控制信息通过任务描述符(task_struct)进行管理和维护。本文将深入探讨进程的概念及其关键数据结构task_struct,解析其在操作系统中的作用和实现机制。 ... [详细]
  • Java中高级工程师面试必备:JVM核心知识点全面解析
    对于软件开发人员而言,随着技术框架的不断演进和成熟,许多高级功能已经被高度封装,使得初级开发者只需掌握基本用法即可迅速完成项目。然而,对于中高级工程师而言,深入了解Java虚拟机(JVM)的核心知识点是必不可少的。这不仅有助于优化性能和解决复杂问题,还能在面试中脱颖而出。本文将全面解析JVM的关键概念和技术细节,帮助读者全面提升技术水平。 ... [详细]
  • ESP32 IRAM 内存优化策略与实践总结
    本文总结了针对ESP32 IRAM内存溢出问题的优化策略与实践经验。通过详细分析ESP32的内存结构和IRAM分配机制,提出了一系列有效的解决方案,包括代码优化、内存管理技巧和编译器配置调整,旨在帮助开发者有效解决`.espressif/tools/xtensa-esp32-elf/esp-2`等类似错误,提升系统性能和稳定性。 ... [详细]
  • 全面解析Java虚拟机:内存模型深度剖析 ... [详细]
  • 如何在Java中高效构建WebService
    本文介绍了如何利用XFire框架在Java中高效构建WebService。XFire是一个轻量级、高性能的Java SOAP框架,能够简化WebService的开发流程。通过结合MyEclipse集成开发环境,开发者可以更便捷地进行项目配置和代码编写,从而提高开发效率。此外,文章还详细探讨了XFire的关键特性和最佳实践,为读者提供了实用的参考。 ... [详细]
  • 负载均衡基础概念与技术解析
    随着互联网应用的不断扩展,用户流量激增,业务复杂度显著提升,单一服务器已难以应对日益增长的负载需求。负载均衡技术应运而生,通过将请求合理分配到多个服务器,有效提高系统的可用性和响应速度。本文将深入探讨负载均衡的基本概念和技术原理,分析其在现代互联网架构中的重要性及应用场景。 ... [详细]
author-avatar
丿车荣璇
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有