秉火429笔记之八 RCC时钟
目录
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时钟相关推荐
- 秉火429笔记之十二 看门狗
目录 1. 概述 2. 独立看门狗(IWDG) 3. 窗口看门狗(WWDG) 1. 概述 STM32有两个看门狗,一个是独立看门狗,另外一个是窗口看门狗,独立看门狗号称宠物狗,窗口看门狗号称警犬. 一 ...
- 秉火429笔记之十八 ETH--以太网
目录 1. 以太网简介 2. SMI 接口 (站管理接口) 2.1 SMI帧格式 2.2 SMI 读写操作 3. MII 和 RMII接口 4. MAC 802.3 4.1 MAC 802.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 ...
- 秉火429笔记之十四 USART--串口通信
目录 1. 串口通讯协议简介 1.1 物理层 1.2 协议层 2 ST USART 2.1 功能引脚 2.2 重要状态 2.3 编程要点 2.4 代码实例 1. 串口通讯协议简介 串口通讯(Seri ...
- 秉火429笔记之九 中断应用概述
目录 1. 中断类型 2. NVIC 概述 3. 中断优先级 4. 优先级分组 5. 编程要点 1. 中断类型 在此不严格区分中断和异常,即简单的认为中断与异常一个概念. M4 内核搭载了异常响应系 ...
- 秉火429笔记之五控制RGB彩灯
1. RGB彩灯混色 RGB彩灯实际上由三盏分别为红.绿.蓝的LED灯组成的,通过控制RGB颜色强度的组合,可以混合出各种彩色. /* 基本混色*/// LED1(R)/ LED2(G)/ LED3( ...
- 秉火429笔记之十三 通信基本概念
目录 1. 串口通讯与并口通讯 2. 全双工.半双工及单工通讯 3. 同步通讯与异步通讯 4. 通信速率 1. 串口通讯与并口通讯 按数据传送的方式,通讯可分为串行通讯与并行通讯,串行通讯是指设备之间 ...
- 秉火429笔记之十一 Systick--滴答定时器
目录 1. 概述 2. 寄存器说明 3. 编程要点 4. 实例代码 SysTick-系统定时器是属于CM4内核中的一个外设,内嵌在NVIC中.系统定时器是一个24bit的向下递减的计数器.所有基于CM ...
- 秉火429笔记之十 EXTI-外部中断/事件
目录 1. EXTI 简介 2. EXTI 功能框图 3. 功能点 4. 编码要点 1. EXTI 简介 外部中断/事件控制器(EXTI)管理了控制器的23个中断/事件线.每个中断/事件线都对应有一个 ...
最新文章
- 【转】statfs获得硬盘使用情况 模拟linux命令 df
- mysql 和 sqlserver中备份一张表的区别
- 全排列问题pascal解题程序
- 8 MyBatis动态SQL
- 写jQuery插件该注意的
- weedfs文件使用记录
- [css] 不用换行的标签,怎么伪元素实现换行的效果?
- 谷歌更新TensorFlow目标检测API
- 文件共享存储主备实时热备实现方案
- ecshop轻松实现不同商品调用不同模板
- Java中的反射和Java中的访问修饰符
- NYOJ 81:炮兵阵地(状压DP)
- 《在近端对回传音频的检测和抑制》笔记
- MVC学习五:Razor布局页面 _ViewStart.cshtml
- OpenCV 之 角点检测
- 几个比较好用的爬虫库
- 计算机IP地址pin,怎样PIN ip地址
- 小米手机获取root权限完整详细教程,亲测可用(精)
- pkg-config
- 视频回顾 | Pulsar Summit Asia 2020 · 场景案例(上):即时零售, 金融证券, 物联网, 电信计费等...