目录

1. RCC 作用概述

2. RCC框图剖析—时钟树

3. 编程要点

4. 源码实例


1. RCC 作用概述

RCC :reset clock control 复位和时钟控制器。

设置系统时钟SYSCLK、设置AHB分频因子(决定HCLK等于多少)、设置APB2分频因子(决定PCLK2等于多少)、设置APB1分频因子(决定PCLK1等于多少)、设置各个外设的分频因子;控制AHB、APB2和APB1这三条总线时钟的开启、控制每个外设的时钟的开启。对于SYSCLK、HCLK、PCLK2、PCLK1这四个时钟的配置一般是:HCLK = SYSCLK=PLLCLK = 180M,PCLK1=HCLK/2 = 90M,PCLK1=HCLK/4 = 45M。如果需要使用USB,HCLK=168M为宜。

2. RCC框图剖析—时钟树

数据手册F429 时钟树

  • HSE 高速外部时钟信号

外部时钟信号,可由有源晶振或无源晶振提供,频率范围 4-26MHZ。若使用HSE作为时钟源,当HSE故障时,将会切换到HSI,直到HSE恢复正常,HSI=16MHZ.

  • 锁相环PLL

PLL的主要作用是对时钟进行倍频,然后把时钟输出到各个功能部件。PLL有两个,一个是主PLL,另外一个是专用的PLLI2S,他们均由HSE或者HSI提供时钟输入信号.

主PLL有两路的时钟输出,第一个输出时钟PLLCLK用于系统时钟,F429里面最高是180M,第二个输出用于USB OTG FS的时钟(48M)、RNG和SDIO时钟(<=48M)。专用的PLLI2S用于生成精确时钟,给I2S提供时钟。

HSE或者HSI经过PLL时钟输入分频因子M(2~63)分频后,成为VCO的时钟输入,VCO的时钟必须在1~2M之间,我们选择HSE=25M作为PLL的时钟输入,M设置为25,那么VCO输入时钟就等于1M.

VCO输入时钟经过VCO倍频因子N倍频之后,成为VCO时钟输出,VCO时钟必须在192~432M之间。我们配置N为360,则VCO的输出时钟等于360M。如果要把系统时钟超频,就得在VCO倍频系数N这里做手脚。PLLCLK_OUTMAX = VCOCLK_OUTMAX/P_MIN = 432/2=216M,即F429最高可超频到216M。

VCO输出时钟之后有三个分频因子:PLLCLK分频因子p,USB OTG FS/RNG/SDIO时钟分频因子Q,分频因子R(F446才有,F429没有)。p可以取值2、4、6、8,我们配置为2,则得到PLLCLK=180M。Q可以取值4~15,但是USB OTG FS必须使用48M,Q=VCO输出时钟360/48=7.5,出现了小数这明显是错误,权衡之策是是重新配置VCO的倍频因子N=336,VCOCLK=1M*336=336M,PLLCLK=VCOCLK/2=168M,USBCLK=336/7=48M,细心的读者应该发现了,在使用USB的时候,PLLCLK被降低到了168M,不能使用180M,这实乃ST的一个奇葩设计。因此,通常对时钟无高速需求的情况下,配置为168M为宜。

  • 系统时钟SYSCLK

系统时钟来源可以是:HSI、PLLCLK、HSE,具体的由时钟配置寄存器RCC_CFGR的SW位配置.

  • AHB总线时钟HCLK

系统时钟SYSCLK经过AHB预分频器分频之后得到时钟叫APB总线时钟,即HCLK,分频因子可以是:[1,2,4,8,16,64,128,256,512],具体的由时钟配置寄存器RCC_CFGR的HPRE位设置。

通常情况下,设置为1分频,即HCLK=SYSCLK。

  • APB2总线时钟HCLK2

APB2总线时钟PCLK2由HCLK经过高速APB2预分频器得到,分频因子可以是:[1,2,4,8,16],具体由时钟配置寄存器RCC_CFGR的PPRE2位设置。。HCLK2属于高速的总线时钟,片上高速的外设就挂载到这条总线上.

通常情况下,设置为2分频,即PCLK2 = HCLK /2。

  • APB1总线时钟HCLK1

APB1总线时钟PCLK1由HCLK经过低速APB预分频器得到,分频因子可以是:[1,2,4,8,16],具体由时钟配置寄存器RCC_CFGR的PPRE1位设置。HCLK1属于低速的总线时钟,最高为45M,片上低速的外设就挂载到这条总线上.

通常情况下,设置为4分频,即PCLK1 = HCLK/4。

  • RTC时钟

RTCCLK 时钟源可以是 HSE 1 MHz( HSE 由一个可编程的预分频器分频)、 LSE 或者 LSI时钟。选择方式是编程 RCC 备份域控制寄存器 (RCC_BDCR) 中的 RTCSEL[1:0] 位和 RCC时钟配置寄存器 (RCC_CFGR) 中的 RTCPRE[4:0] 位。所做的选择只能通过复位备份域的方式修改。我们通常的做法是由LSE给RTC提供时钟,大小为32.768KHZ。LSE由外接的晶体谐振器产生,所配的谐振电容精度要求高,不然很容易不起震。

  • 独立看门狗时钟

独立看门狗时钟由内部的低速时钟LSI提供,大小为32KHZ

  • I2S时钟

I2S时钟可由外部的时钟引脚I2S_CKIN输入,也可由专用的PLLI2SCLK提供,具体的由RCC 时钟配置寄存器 (RCC_CFGR)的I2SSCR位配置。我们在使用I2S外设驱动W8978的时候,使用的时钟是PLLI2SCLK,这样就可以省掉一个有源晶振。

  • ETH PHY以太网时钟

429要想实现以太网功能,除了有本身内置的MAC之外,还需要外接一个PHY芯片,常见的PHY芯片有DP83848和LAN8720,其中DP83848支持MII和RMII接口,LAN8720只支持RMII接口。秉火F429开发板用的是RMII接口,选择的PHY芯片是LAB8720。使用RMII接口的好处是使用的IO减少了一半,速度还是跟MII接口一样。当使用RMII接口时,PHY芯片只需输出一路时钟给MCU即可,如果是MII接口,PHY芯片则需要提供两路时钟给MCU。

  • USB PHY时钟

F429的USB没有集成PHY,要想实现USB高速传输的话,必须外置USB PHY芯片,常用的芯片是USB3300。当外接USB PHY芯片时,PHY芯片需要给MCU提供一个时钟。外扩USB3300会占用非常多的IO,跟SDRAM和RGB888的IO会复用的很厉害。

  • MCO时钟输出

MCO是microcontroller clock output的缩写,是微控制器时钟输出引脚,主要作用是可以对外提供时钟,相当于一个有源晶振。F429中有两个MCO,由PA8/PC9复用所得。MCO1所需的时钟源通过 RCC 时钟配置寄存器 (RCC_CFGR) 中的 MCO1PRE[2:0] 和 MCO1[1:0]位选择。MCO2所需的时钟源通过 RCC 时钟配置寄存器 (RCC_CFGR) 中的 MCO2PRE[2:0] 和 MCO2位选择。

3. 编程要点

  • 开启HSE/HSI ,并等待 HSE/HSI 稳定
  • 设置 AHB、APB2、APB1的预分频因子
  • 设置PLL的时钟来源,设置VCO输入时钟 分频因子PLL_M,设置VCO输出时钟
  • 倍频因子PLL_N,设置PLLCLK时钟分频因子PLL_P,设置OTG FS,SDIO,RNG
  • 时钟分频因子 PLL_Q
  • 开启PLL,并等待PLL稳定
  • 把PLLCK切换为系统时钟SYSCLK
  • 读取时钟切换状态位,确保PLLCLK被选为系统时钟
  • 官方有快捷配置工具

4. 源码实例

#include "./rcc/bsp_clkconfig.h"
#include "stm32f4xx_rcc.h"/** 使用HSE时,设置系统时钟的步骤* 1、开启HSE ,并等待 HSE 稳定* 2、设置 AHB、APB2、APB1的预分频因子* 3、设置PLL的时钟来源*    设置VCO输入时钟 分频因子        m*    设置VCO输出时钟 倍频因子        n*    设置PLLCLK时钟分频因子          p*    设置OTG FS,SDIO,RNG时钟分频因子 q* 4、开启PLL,并等待PLL稳定* 5、把PLLCK切换为系统时钟SYSCLK* 6、读取时钟切换状态位,确保PLLCLK被选为系统时钟*//** m: VCO输入时钟 分频因子,取值2~63* n: VCO输出时钟 倍频因子,取值192~432* p: PLLCLK时钟分频因子  ,取值2,4,6,8* q: OTG FS,SDIO,RNG时钟分频因子,取值4~15* 函数调用举例,使用HSE设置时钟* SYSCLK=HCLK=180M,PCLK2=HCLK/2=90M,PCLK1=HCLK/4=45M* HSE_SetSysClock(25, 360, 2, 7);* HSE作为时钟来源,经过PLL倍频作为系统时钟,这是通常的做法* 系统时钟超频到216M爽一下* HSE_SetSysClock(25, 432, 2, 9);*/
void HSE_SetSysClock(uint32_t m, uint32_t n, uint32_t p, uint32_t q)
{__IO uint32_t HSEStartUpStatus = 0;// 使能HSE,开启外部晶振,秉火F429使用 HSE=25MRCC_HSEConfig(RCC_HSE_ON);// 等待HSE启动稳定HSEStartUpStatus = RCC_WaitForHSEStartUp();if (HSEStartUpStatus == SUCCESS){// 调压器电压输出级别配置为1,以便在器件为最大频率// 工作时使性能和功耗实现平衡RCC->APB1ENR |= RCC_APB1ENR_PWREN;PWR->CR |= PWR_CR_VOS;// HCLK = SYSCLK / 1RCC_HCLKConfig(RCC_SYSCLK_Div1);// PCLK2 = HCLK / 2RCC_PCLK2Config(RCC_HCLK_Div2);// PCLK1 = HCLK / 4RCC_PCLK1Config(RCC_HCLK_Div4);// 如果要超频就得在这里下手啦// 设置PLL来源时钟,设置VCO分频因子m,设置VCO倍频因子n,//  设置系统时钟分频因子p,设置OTG FS,SDIO,RNG分频因子qRCC_PLLConfig(RCC_PLLSource_HSE, m, n, p, q);// 使能PLLRCC_PLLCmd(ENABLE);// 等待 PLL稳定while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET){}   /*-----------------------------------------------------*///开启 OVER-RIDE模式,以能达到更高频率PWR->CR |= PWR_CR_ODEN;while((PWR->CSR & PWR_CSR_ODRDY) == 0){}PWR->CR |= PWR_CR_ODSWEN;while((PWR->CSR & PWR_CSR_ODSWRDY) == 0){}      // 配置FLASH预取指,指令缓存,数据缓存和等待状态FLASH->ACR = FLASH_ACR_PRFTEN | FLASH_ACR_ICEN | FLASH_ACR_DCEN | FLASH_ACR_LATENCY_5WS;
/*-----------------------------------------------------*/// 当PLL稳定之后,把PLL时钟切换为系统时钟SYSCLKRCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);// 读取时钟切换状态位,确保PLLCLK被选为系统时钟while (RCC_GetSYSCLKSource() != 0x08){}}else{ // HSE启动出错处理while (1){}}
}/** 使用HSI时,设置系统时钟的步骤* 1、开启HSI ,并等待 HSI 稳定* 2、设置 AHB、APB2、APB1的预分频因子* 3、设置PLL的时钟来源*    设置VCO输入时钟 分频因子        m*    设置VCO输出时钟 倍频因子        n*    设置SYSCLK时钟分频因子          p*    设置OTG FS,SDIO,RNG时钟分频因子 q* 4、开启PLL,并等待PLL稳定* 5、把PLLCK切换为系统时钟SYSCLK* 6、读取时钟切换状态位,确保PLLCLK被选为系统时钟*//** m: VCO输入时钟 分频因子,取值2~63* n: VCO输出时钟 倍频因子,取值192~432* p: PLLCLK时钟分频因子  ,取值2,4,6,8* q: OTG FS,SDIO,RNG时钟分频因子,取值4~15* 函数调用举例,使用HSI设置时钟* SYSCLK=HCLK=180M,PCLK2=HCLK/2=90M,PCLK1=HCLK/4=45M* HSI_SetSysClock(16, 360, 2, 7);* HSE作为时钟来源,经过PLL倍频作为系统时钟,这是通常的做法* 系统时钟超频到216M爽一下* HSI_SetSysClock(16, 432, 2, 9);*/void HSI_SetSysClock(uint32_t m, uint32_t n, uint32_t p, uint32_t q)
{__IO uint32_t HSIStartUpStatus = 0;// 把RCC外设初始化成复位状态RCC_DeInit();//使能HSI, HSI=16MRCC_HSICmd(ENABLE);// 等待 HSI 就绪HSIStartUpStatus = RCC->CR & RCC_CR_HSIRDY;// 只有 HSI就绪之后则继续往下执行if (HSIStartUpStatus == RCC_CR_HSIRDY){// 调压器电压输出级别配置为1,以便在器件为最大频率// 工作时使性能和功耗实现平衡RCC->APB1ENR |= RCC_APB1ENR_PWREN;PWR->CR |= PWR_CR_VOS;// HCLK = SYSCLK / 1RCC_HCLKConfig(RCC_SYSCLK_Div1);// PCLK2 = HCLK / 2RCC_PCLK2Config(RCC_HCLK_Div2);// PCLK1 = HCLK / 4RCC_PCLK1Config(RCC_HCLK_Div4);// 如果要超频就得在这里下手啦// 设置PLL来源时钟,设置VCO分频因子m,设置VCO倍频因子n,//  设置系统时钟分频因子p,设置OTG FS,SDIO,RNG分频因子qRCC_PLLConfig(RCC_PLLSource_HSI, m, n, p, q);// 使能PLLRCC_PLLCmd(ENABLE);// 等待 PLL稳定while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET){}   /*-----------------------------------------------------*///开启 OVER-RIDE模式,以能达到更高频率PWR->CR |= PWR_CR_ODEN;while((PWR->CSR & PWR_CSR_ODRDY) == 0){}PWR->CR |= PWR_CR_ODSWEN;while((PWR->CSR & PWR_CSR_ODSWRDY) == 0){}      // 配置FLASH预取指,指令缓存,数据缓存和等待状态FLASH->ACR = FLASH_ACR_PRFTEN | FLASH_ACR_ICEN |FLASH_ACR_DCEN |FLASH_ACR_LATENCY_5WS;
/*-----------------------------------------------------*/// 当PLL稳定之后,把PLL时钟切换为系统时钟SYSCLKRCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);// 读取时钟切换状态位,确保PLLCLK被选为系统时钟while (RCC_GetSYSCLKSource() != 0x08){}}else{ // HSI启动出错处理while (1){}}
}// MCO1 PA8 GPIO 初始化
void MCO1_GPIO_Config(void)
{GPIO_InitTypeDef GPIO_InitStructure;RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);// MCO1 GPIO 配置GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;GPIO_InitStructure.GPIO_PuPd = 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 = GPIO_Pin_9;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;  GPIO_Init(GPIOC, &GPIO_InitStructure);
}

秉火429笔记之八 RCC时钟相关推荐

  1. 秉火429笔记之十二 看门狗

    目录 1. 概述 2. 独立看门狗(IWDG) 3. 窗口看门狗(WWDG) 1. 概述 STM32有两个看门狗,一个是独立看门狗,另外一个是窗口看门狗,独立看门狗号称宠物狗,窗口看门狗号称警犬. 一 ...

  2. 秉火429笔记之十八 ETH--以太网

    目录 1. 以太网简介 2.  SMI 接口 (站管理接口) 2.1 SMI帧格式 2.2 SMI 读写操作 3. MII 和 RMII接口 4. MAC 802.3 4.1 MAC 802.3 帧格 ...

  3. 秉火429笔记之十七 SPI--操作FLASH

    目录 1. SPI协议概述 2. STM32 SPI特性及架构 2.1 SPI外设简介 2.2 STM32的SPI架构剖析 2.2.1 通讯引脚 2.2.2 时钟控制逻辑 2.2.3 数据控制逻辑 3 ...

  4. 秉火429笔记之十四 USART--串口通信

    目录 1. 串口通讯协议简介 1.1 物理层 1.2 协议层 2  ST USART 2.1 功能引脚 2.2 重要状态 2.3 编程要点 2.4 代码实例 1. 串口通讯协议简介 串口通讯(Seri ...

  5. 秉火429笔记之九 中断应用概述

    目录 1. 中断类型 2. NVIC 概述 3.  中断优先级 4. 优先级分组 5. 编程要点 1. 中断类型 在此不严格区分中断和异常,即简单的认为中断与异常一个概念. M4 内核搭载了异常响应系 ...

  6. 秉火429笔记之五控制RGB彩灯

    1. RGB彩灯混色 RGB彩灯实际上由三盏分别为红.绿.蓝的LED灯组成的,通过控制RGB颜色强度的组合,可以混合出各种彩色. /* 基本混色*/// LED1(R)/ LED2(G)/ LED3( ...

  7. 秉火429笔记之十三 通信基本概念

    目录 1. 串口通讯与并口通讯 2. 全双工.半双工及单工通讯 3. 同步通讯与异步通讯 4. 通信速率 1. 串口通讯与并口通讯 按数据传送的方式,通讯可分为串行通讯与并行通讯,串行通讯是指设备之间 ...

  8. 秉火429笔记之十一 Systick--滴答定时器

    目录 1. 概述 2. 寄存器说明 3. 编程要点 4. 实例代码 SysTick-系统定时器是属于CM4内核中的一个外设,内嵌在NVIC中.系统定时器是一个24bit的向下递减的计数器.所有基于CM ...

  9. 秉火429笔记之十 EXTI-外部中断/事件

    目录 1. EXTI 简介 2. EXTI 功能框图 3. 功能点 4. 编码要点 1. EXTI 简介 外部中断/事件控制器(EXTI)管理了控制器的23个中断/事件线.每个中断/事件线都对应有一个 ...

最新文章

  1. 【转】statfs获得硬盘使用情况 模拟linux命令 df
  2. mysql 和 sqlserver中备份一张表的区别
  3. 全排列问题pascal解题程序
  4. 8 MyBatis动态SQL
  5. 写jQuery插件该注意的
  6. weedfs文件使用记录
  7. [css] 不用换行的标签,怎么伪元素实现换行的效果?
  8. 谷歌更新TensorFlow目标检测API
  9. 文件共享存储主备实时热备实现方案
  10. ecshop轻松实现不同商品调用不同模板
  11. Java中的反射和Java中的访问修饰符
  12. NYOJ 81:炮兵阵地(状压DP)
  13. 《在近端对回传音频的检测和抑制》笔记
  14. MVC学习五:Razor布局页面 _ViewStart.cshtml
  15. OpenCV 之 角点检测
  16. 几个比较好用的爬虫库
  17. 计算机IP地址pin,怎样PIN ip地址
  18. 小米手机获取root权限完整详细教程,亲测可用(精)
  19. pkg-config
  20. 视频回顾 | Pulsar Summit Asia 2020 · 场景案例(上):即时零售, 金融证券, 物联网, 电信计费等...

热门文章

  1. android -------- Hawk数据库
  2. 如何避免陷入流量旋涡
  3. couldn't set tty to ppp discipline invalid argument
  4. JDK和KRE安装及其区别
  5. 前端工具-Yeoman模板 + 接收用户输入
  6. EXPLAINING AND HARNESSING ADVERSARIAL EXAMPLES 论文笔记
  7. 网上购车平台蛋蛋订车上私户,汽车之家青少年嘉年华正式开幕
  8. siri语音功能测试点
  9. SQL Server新增Contained Database功能
  10. stm32wb55 基于rtt的ble sample制作过程