再造STM32---第十三部分:RCC—使用 HSE/HSI 配置时钟

2019-09-28来源: eefocus关键字:STM32  RCC  HSE  HSI  配置时钟

       配合《STM32F4xx 中文参考手册》 RCC 章节一起阅读,效果会更佳,特别是涉及到寄存器说明的部分。

       RCC : reset clock control 复位和时钟控制器。本章我们主要讲解时钟部分,特别是要着重理解时钟树,理解了时钟树, F429 的一切时钟的来龙去脉都会了如指掌。



13.1 RCC 主要作用—时钟部分:

       设置系统时钟 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。这个时钟配置也是库函数的标准配置,我们用的最多的就是这个。


13.2 RCC 框图剖析—时钟树:

       时钟树单纯讲理论的话会比较枯燥,如果选取一条主线,并辅以代码,先主后次讲解的话会很容易,而且记忆还更深刻。我们这里选取库函数时钟系统时钟函数:SetSysClock(); 以这个函数的编写流程来讲解时钟树,这个函数也是我们用库的时候默认的系统时钟设置函数。该函数的功能是利用 HSE 把时钟设置为: HCLK = SYSCLK=PLLCLK= 180M, PCLK1=HCLK/2 = 90M, PCLK1=HCLK/4 = 45M 下面我们就以这个代码的流程为主线, 来分析时钟树,对应的是图中的黄色部分,代码流程在时钟树中以数字的大小顺序标识。

13.2.1 系统时钟:

1. ①HSE 高速外部时钟信号:

        HSE 是高速的外部时钟信号,可以由有源晶振或者无源晶振提供,频率从 4-26MHZ不等。当使用有源晶振时,时钟从 OSC_IN 引脚进入, OSC_OUT 引脚悬空,当选用无源晶振时,时钟从 OSC_IN 和 OSC_OUT 进入,并且要配谐振电容。 HSE 我们使用 25M 的无源晶振。 如果我们使用 HSE 或者 HSE 经过 PLL 倍频之后的时钟作为系统时钟 SYSCLK,当 HSE 故障时候,不仅 HSE 会被关闭, PLL 也会被关闭,此时高速的内部时钟时钟信号HSI 会作为备用的系统时钟,直到 HSE 恢复正常, HSI=16M。

2. ②锁相环 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 必须使用 ,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 的一个奇葩设计。有关 PLL 的配置有一个专门的RCC PLL 配置寄存器 RCC_PLLCFGR,具体描述看手册即可。

        PLL 的时钟配置经过,稍微整理下可由如下公式表达:


        VCOCLK_IN = PLLCLK_IN / M = HSE / 25 = 1M

        VCOCLK_OUT = VCOCLK_IN * N = 1M * 360 = 360M

        PLLCLK_OUT=VCOCLK_OUT/P=360/2=180M

        USBCLK = VCOCLK_OUT/Q=360/7=51.7。暂时这样配置,到真正使用 USB 的时候会重新配置。

3. ③系统时钟 SYSCLK:

        系统时钟来源可以是: HSI、 PLLCLK、 HSE,具体的由时钟配置寄存器 RCC_CFGR的 SW 位配置。我们这里设置系统时钟: SYSCLK = PLLCLK = 180M。 如果系统时钟是由HSE 经过 PLL 倍频之后的 PLLCLK 得到,当 HSE 出现故障的时候,系统时钟会切换为HSI=16M,直到 HSE 恢复正常为止。

4. ④AHB 总线时钟 HCLK:

        系统时钟 SYSCLK 经过 AHB 预分频器分频之后得到时钟叫 APB 总线时钟,即 HCLK,分频因子可以是:[1,2,4,8,16,64,128,256,512],具体的由时钟配置寄存器RCC_CFGR 的 HPRE 位设置。片上大部分外设的时钟都是经过 HCLK 分频得到,至于 AHB总线上的外设的时钟设置为多少,得等到我们使用该外设的时候才设置,我们这里只需粗线条的设置好 APB 的时钟即可。 我们这里设置为 1 分频,即 HCLK=SYSCLK=180M。

5. ⑤APB2 总线时钟 HCLK2:

        APB2 总线时钟 PCLK2 由 HCLK 经过高速 APB2 预分频器得到,分频因子可以是:[1,2,4,8,16],具体由时钟配置寄存器 RCC_CFGR 的 PPRE2 位设置。 HCLK2 属于高速的总线时钟,片上高速的外设就挂载到这条总线上,比如全部的 GPIO、 USART1、 SPI1等。至于 APB2 总线上的外设的时钟设置为多少,得等到我们使用该外设的时候才设置,我们这里只需粗线条的设置好 APB2 的时钟即可。我们这里设置为 2 分频,即 PCLK2 =HCLK /2= 90M。

6. ⑥APB1 总线时钟 HCLK1:

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

USART2/3/4/5、 SPI2/3, I2C1/2 等。至于 APB1 总线上的外设的时钟设置为多少,得等到我们使用该外设的时候才设置,我们这里只需粗线条的设置好 APB1 的时钟即可。我们这里设置为 4 分频,即 PCLK1 = HCLK/4 = 45M。

7. 设置系统时钟库函数:

       上面的 6 个步骤对应的设置系统时钟库函数如下,为了方便阅读,已经把跟 429 不相关的代码删掉,把英文注释翻译成了中文,并把代码标上了序号,总共 6 个步骤。该函数是直接操作寄存器的,有关寄存器部分请参考数据手册的 RCC 的寄存器描述部分。


/*

* 使用 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 被选为系统时钟

*/

#define PLL_M 25

#define PLL_N 360

#define PLL_P 2

#define PLL_Q 7

/////////如果要超频的话,修改 PLL_N 这个宏即可,取值范围为: 192~432。////////

oid SetSysClock(void)

{

__IO uint32_t StartUpCounter = 0, HSEStatus = 0;

// ①使能 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;

// ②设置 AHB/APB2/APB1 的分频因子

// HCLK = SYSCLK / 1

RCC->CFGR |= RCC_CFGR_HPRE_DIV1;

// PCLK2 = HCLK / 2

RCC->CFGR |= RCC_CFGR_PPRE2_DIV2;

// PCLK1 = HCLK / 4

RCC->CFGR |= RCC_CFGR_PPRE1_DIV4;

// ③配置主 PLL 的时钟来源,设置 M,N,P,Q

// Configure the main PLL

RCC->PLLCFGR = PLL_M|(PLL_N<<6)|

(((PLL_P >> 1) -1) << 16) |

(RCC_PLLCFGR_PLLSRC_HSE) |

(PLL_Q << 24);

// ④使能主 PLL

RCC->CR |= RCC_CR_PLLON;

// 等待 PLL 稳定

while ((RCC->CR & RCC_CR_PLLRDY) == 0) {

}

/*--------------------------------------------------

// 开启 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;

/*--------------------------------------------------

// ⑤选择主 PLLCLK 作为系统时钟源

RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));

RCC->CFGR |= RCC_CFGR_SW_PLL;

// ⑥读取时钟切换状态位,确保 PLLCLK 选为系统时钟

while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS )

!= RCC_CFGR_SWS_PLL);

{

}

} else {

//

[1] [2] [3] [4] [5]
关键字:STM32  RCC  HSE  HSI  配置时钟 编辑:什么鱼 引用地址:http://news.eeworld.com.cn/mcu/ic476014.html 本网站转载的所有的文章、图片、音频视频文件等资料的版权归版权所有人所有,本站采用的非本站原创文章及图片等内容无法一一联系确认版权者。如果本网所选内容的文章作者及编辑认为其作品不宜公开自由传播,或不应无偿使用,请及时通过电子邮件或电话通知我们,以迅速采取适当措施,避免给双方造成不必要的经济损失。

上一篇:再造STM32---第十四部分:STM32 中断应用概览
下一篇:再造STM32---第十二部分:启动文件详解

关注eeworld公众号 快捷获取更多信息
关注eeworld公众号
快捷获取更多信息
关注eeworld服务号 享受更多官方福利
关注eeworld服务号
享受更多官方福利

推荐阅读

stm32 看门狗 BKP(HAL库)
(一)概述stm32有两个看门狗:硬件看门狗(LSI 40KHz,时间精度不高)和窗口看门狗(APB1)。(二)硬件看门狗实现代码IWDG_HandleTypeDef hiwdg; // 硬件看门狗初始化static void MX_IWDG_Init(IWDG_HandleTypeDef *pHiwdg){    pHiwdg->Instance = IWDG;    pHiwdg->Init.Prescaler = IWDG_PRESCALER_4;    pHiwdg->Init.Reload = 0xFFF; // Tout
发表于 2019-11-16
STM32 HAL库学习系列第11篇---定时器TIM---看门狗基本配置及使用
基本配置使用cube配置溢出时间记住准时喂狗独立看门狗: /* IWDG 1s 超时溢出 */  MX_IWDG_Init(IWDG_PRESCALER_64,625);  /* 启动独立看门狗 */  HAL_IWDG_Start(&hiwdg);   LED1_ON;   /* while部分是我们在项目中具体需要写的代码,这部分的程序可以用独立看门狗来监控   * 如果我们知道这部           分代码的执行时间,比如是50ms,那么我们可以设置独立看门狗的 &nb
发表于 2019-11-16
STM32-自学笔记(18.独立看门狗,使用到的库函数)
为16IWDG_Prescaler_256设置IWDG预分频值为256IWDG_Prescaler_32设置IWDG预分频值为32例子:IWDG_SetPrescaler(IWDG_Prescaler_8);                //设置IWDG预分频值为82.IWDG_SetReload函数原型:void IWDG_SetReload(u16 Reload)功能:设置IWDG重装载值参数:Reload:IWDG的重装载值。取值范围0~0x0FFF例子:IWDG_SetReload(0xFFF);       
发表于 2019-11-16
HAL库 STM32CubeMX教程五----看门狗(独立看门狗,窗口看门狗)
的工作常常会受到来自外界电磁场的干扰,造成程序的跑飞,而陷入死循环;或者因为用户配置代码出现BUG,导致芯片无法正常工作,出于对单片机运行状态进行实时监测的考虑,便产生了一种专门用于监测单片机程序运行状态的模块或者芯片,俗称“看门狗”(watchdog) 简单说:看门狗的本质就是定时计数器,计数器使能之后一直在累加 而喂狗就是重新写入计数器的值,时计数器重新累加,如果在一定时间内没有接收到喂狗信号(表示MCU已经挂了),便实现处理器的自动复位重启(发送复位信号)STM32的内置看门狗STM32内置两个看门狗,提供了更高的安全性、时间的精确性和使用的灵活性。两个看门狗设备(独立看门狗、窗口看门狗)可以用来检测和解决由软件错误
发表于 2019-11-16
HAL库 STM32CubeMX教程五----看门狗(独立看门狗,窗口看门狗)
怎样用STM32CAN总线接口发送和接收数据
,禁止高7位都为隐性,即不能:ID=1111111XXXX。RTR,远程请求位。0,数据帧;1, 远程帧;SRR,替代远程请求位。设置为1(隐性电平);IDE,标识符选择位。0,标准标识符;1,扩展标识符;r0,r1:保留位。必须以显现电平发送,但是接收可以是隐性电平。DLC:数据长度码。0~8,表示发送/接收的数据长度(字节)。IDE,标识符选择位。0,标准标识符;1,扩展标识符;位时序分解为了实现位同步,CAN协议把每一个数据位的时序分解成SS段、PTS段、PBS1段、PBS2段,这四段的长度加起来即为一个CAN数据位的长度。分解后最小的时间单位是Tq,而一个完整的位由8~25个Tq组成。STM32中的CAN接口STM32的芯片
发表于 2019-11-16
怎样用STM32CAN总线接口发送和接收数据
stm8s_iwdg(独立看门狗)
; IWDG_Prescaler_16  = (uint8_t)0x02, /*!< Used to set prescaler register to 16 */  IWDG_Prescaler_32  = (uint8_t)0x03, /*!< Used to set prescaler register to 32 */  IWDG_Prescaler_64  = (uint8_t)0x04, /*!< Used to set prescaler register to 64 */  IWDG_Prescaler_128 = (uint8_t
发表于 2019-11-16
小广播
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号 电信业务审批[2006]字第258号函 京公海网安备110108001534 Copyright © 2005-2019 EEWORLD.com.cn, Inc. All rights reserved