STM32开发笔记04---配置系统时间

架构图

思考重点

  • 本文的目的是使用HSE外部晶振来配置系统时钟
  • 参考手册中的时钟树如何理解
  • 理解开发版初始化过程中对系统时钟的操作
  • 如何自行变更系统时钟

配置时钟源

在开发版STM32F429,以HSE, HSI, PLL作为主要的系统时钟的信号来源,并拥有LSI, LSE低速内外部信号时钟源,两者频率分别为32, 32.768kHz

时钟源相当于节拍器的功能,藉由稳定的信号源输出,可以有效配置出单位时间内系统的运算次数。下面探讨三个主要的系统时钟来源的功能与特色:

  • HSE
    • 高速外部时钟信号
    • 可由震盪器(oscillator)/晶振(crystal)提供信号源
    • 选择震盪器为信号源需要接上引脚OSC_OUT, OSC_IN
    • 频率: 4MHz~25MHz
  • HSI
    • 高速内部时钟信号
    • 内部晶振提供信号源
    • 当HSE故障将会自动切成HSI直到HSE恢復正常
    • 频率: 16MHz
  • PLL
    • 锁向环
    • 主要目的是对时钟信号源进行分频以及倍频处理,并将结果输出给相关外设
    • 开发版具有两个PLL,分别是主PLL和I2S专用PLLI2S
    • 官方建议最高运行频率为180MHz
    • 主PLL
      • 用于PLLCLK系统时钟
      • 用于USB OTG FS, RNG, SDIO时钟(48MHz)
    • PLLI2S
      • 用于I2S的时钟

时钟树

上图为reference manual中对设置系统时钟的描述,也就是着名的时钟树框图,由于我们的目标是配製系统时间SYSCLK,因此可以把主线任务从上图的红框部分拆分成以下的流程图,这样对接下来的程式范例也好理解

从图中我们可以发现配置系统时间过程中有两大重点

  1. 选择PLL时钟源
  2. 选择系统时钟源

而系统时间通常是使用HSE, HSI, PLL三者之一,可以透过配置暂存器来选择,一般来说系统时间会使用PLL倍频之后的结果

PLL倍频

由于外部时钟来源的频率不够大,开发版需要透过PLL锁向环,将输入时钟倍频成适合的系统频率。因此PLL的处理过程围绕在将时钟源切分成约1MHz后再进行放大,我们先来看看PLL系统时间的运算公式:

[(HSE/HSI)/分频因子M] * 倍频因子N / PLLCLK分频因子P

操作流程

  1. 选择时钟输入来源: HSE(25MHz)或HSI(16MHz)
  2. 设置分频因子M: 时钟源/M的结果务必在1~2MHz。M的范围: 2~63
  3. 设置倍频因子N : STM32F42xxx, STM32F43xxx系列频率范围: 192~432MHz
  4. 设置PLLCLK分频因子P: P可以是2、4、6、8

举例来说,我们选择25MHz的外部震盪器时钟源,透过将M配置成25,把V时钟输入结果配置成1MHz,然后把N设为360,将输出结果放大成360MHz,最后设置P为2,输出180MHz的PLL系统时钟源

另外假如PLL时钟来源选择HSE,当HSE发生问题时,系统会自动将时钟源切换成HSI

AHB外设时钟HCLK

当我们选择PLL作为系统时钟来源后,首先会输出到高速外设汇流排AHB,同样的我们可以透过软体控制暂存器的AHB分频因子,分频因子可以设置为1, 2, 4, 8, 16, 64, 128, 256, 512。几乎所有周边外设都使用AHB的系统时间频率

APB2外设时钟PCLK2

APB2汇流排时钟经由AHB时钟分频得到,可以透过软体操作暂存器的APB2分频因子,分频因子可以设置为1, 2, 4, 8, 16。需要注意APB2时钟频率不可以超过90MHz

APB1外设时钟PCLK1

APB1汇流排时钟经由AHB时钟分频得到,可以透过软体操作暂存器的APB1分频因子,分频因子可以设置为1, 2, 4, 8, 16。需要注意APB1时钟频率不可以超过45MHz

暂存器介绍

在接下来的系统时钟配置环节主要涉及以下几个暂存器,详细可以参考reference manual

RCC_CR

  • PLLRDY: 主PLL锁向环是否被开启
  • PLLON: 开启PLL锁向环
  • CSSON: 开启检测外部震盪器是否稳定
  • HSEBYP: 当HSE发生问题时bypass给其他时钟信号源
  • HSERDY: 由硬体判断HSE是否被开启
  • HSEON: 开启HSE时钟源
  • HSION: 开启HSI时钟源

RCC_PLLCFGR

  • PLLP: 配置分频因子P
  • PLLN: 配置分频因子N
  • PLLM: 配置分频因子M

RCC_CFGR

  • PPRE2: 配置APB2分频因子
  • PPRE1: 配置APB1分频因子
  • HPRE: 配置AHB分频因子
  • SWS: 等待硬体切换系统时钟来源
  • SW: 选择系统时钟来源

SetSysClock()函式

关于开发版初始化的主要写在函式SystemInit()当中,系统时钟的配置当然也不例外。在SystemInit() 我们可以找到SetSysClock()函式,我们上一小节介绍的诸如PLL时钟设定都在这个函式中完成,以下大致介绍SetSysClock():

  • 目的: 初始化系统时间
  • 主要操作:
    1. 开启HSE
    2. 配置内部电压调节器
    3. 配置AHB/APB1/APB2
    4. 配置PLL
    5. 开启PLL
    6. 开启Over-drive模式
    7. 配置Flash接口暂存器
    8. 将PLL配置成系统时间
static void SetSysClock(void)
{
  __IO uint32_t StartUpCounter = 0, HSEStatus = 0;
  
  /* 开启HSE,操作RCC_CR的HSEON位*/
  RCC->CR |= ((uint32_t)RCC_CR_HSEON);
 
  /* 在指定时间内等待硬体将HSERDY置位成1 */
  do
  {
    HSEStatus = RCC->CR & RCC_CR_HSERDY;
    StartUpCounter++;
  } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));

  /* 查看HSE是否配置成功,或者只是因为timeout退出 */
  if ((RCC->CR & RCC_CR_HSERDY) != RESET)
  {
    HSEStatus = (uint32_t)0x01; // HSE配置成功,将HSEStatus设为1
  }
  else
  {
    HSEStatus = (uint32_t)0x00; // HSE配置失败,将HSEStatus设为0
  }
  /* 若HSE配置成功,则可以开始系统时钟的处理流程 */
  if (HSEStatus == (uint32_t)0x01)
  {
    /* 配置内部电压调节器,以达到效率与功号之间的平衡 */
    RCC->APB1ENR |= RCC_APB1ENR_PWREN;
    PWR->CR |= PWR_CR_VOS;

    /* AHB分频因子配置成1 */
    RCC->CFGR |= RCC_CFGR_HPRE_DIV1;

    /* APB2分频因子配置成2 */
    RCC->CFGR |= RCC_CFGR_PPRE2_DIV2;
    
    /* APB1分频因子配置成4*/
    RCC->CFGR |= RCC_CFGR_PPRE1_DIV4;

    /* 配置RCC_PLLCFGR暂存器,我们主要关注M, N, P因子 */
    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-drive模式,使系统能够运行更高频率 */
    PWR->CR |= PWR_CR_ODEN;
		
	/* 等待Over-drive模式被成功开启 */
    while((PWR->CSR & PWR_CSR_ODRDY) == 0)
    {
    }
  
	/* 将系统切换为Over-drive模式 */	
    PWR->CR |= PWR_CR_ODSWEN;
		
	/* 等待系统成功切换置Over-drive模式 */		
    while((PWR->CSR & PWR_CSR_ODSWRDY) == 0)
    {
    } 
		
    /* 配置Flash接口暂存器 */
    FLASH->ACR = FLASH_ACR_PRFTEN | FLASH_ACR_ICEN |FLASH_ACR_DCEN |FLASH_ACR_LATENCY_5WS;

    /* 选择PLL作为系统时钟来源 */
    RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
    RCC->CFGR |= RCC_CFGR_SW_PLL;

    /* 等待硬体切换系统时钟来源 */
    while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS ) != RCC_CFGR_SWS_PLL);
    {
    }
  }
  else
  { /* 使用者可以自行定义若HSE启动失败要做那些处理 */
  }
}

超频处理

理解了SetSysClock()函式以后我们大致能掌握配置系统时间的操作,若我们想自行编写一个改变PLL系统时钟频率的API,可以简单地抓一下程式编写重点:

  1. 初始化RCC时钟配置成default状态
  2. 开启HSE
  3. 设置AHB/APB2/APB1分频因子
  4. 配置分频因子M, N, P
  5. 开启PLL
  6. 配置PLL为系统时钟来源

还记得在介绍倍频因子N的时候有提到STM32F42xxx, STM32F43xxx系列开发版可以将N设置到最大值432MHz吗?实际上官方参考手册虽建议最大频率为180MHz,不过还是预留空间供超频使用,因此我们希望透过自定义API将系统频率重新设置成216MHz

  • 关键点:
    • 在编写程式前可以先到标准库中阅读库函数
    • 搭配参考手册查阅暂存器设定
    • 参考SetSysClock()
  • 涉及库函式:
  1. RCC_DeInit(void)
  2. RCC_HSEConfig(uint8_t RCC_HSE)
  3. RCC_WaitForHSEStartUp(void)
  4. RCC_PLLConfig(uint32_t RCC_PLLSource, uint32_t PLLM, uint32_t PLLN, uint32_t PLLP, uint32_t PLLQ)
  5. RCC_HCLKConfig(uint32_t RCC_SYSCLK)
  6. RCC_PCLK2Config(uint32_t RCC_HCLK)
  7. RCC_PCLK1Config(uint32_t RCC_HCLK)
  8. RCC_PLLCmd(FunctionalState NewState)
  9. RCC_GetFlagStatus(uint8_t RCC_FLAG)
  10. RCC_SYSCLKConfig(uint32_t RCC_SYSCLKSource)

程式码范例

void My_Delay(__IO uint32_t count){
	for(;count > 0; count--);
}	

/**
 * vco range: 192~432Mhz
 * Re-set system clock by myself, the maximun frequency is 216Mhz
 * @param m Division factor
 * @param n Multiplication factor
 * @param p Division factor for main system clock
 * @param q Division factor for USB OTG FS, SDIO, etc.
 * @retval None
 */
void HSE_SetSysCLK(uint32_t m, uint32_t n, uint32_t p, uint32_t q){
		RCC_DeInit(); // 将RCC重置到预设模式
		RCC_HSEConfig(SET_ON); // 开启HSE

		/* 等待HSE启动成功 */
		while(!RCC_WaitForHSEStartUp()){
			My_Delay(TIMES);
			RCC_HSEConfig(SET_ON);
		}

		/* 配置PLL分倍频因子*/
		RCC_PLLConfig(HSE,m,n,p,q);
		/* 配置外设时钟分频因子*/
		RCC_HCLKConfig(AHB_CFG); // AHB
		RCC_PCLK2Config(APB2_CFG); // APB2
		RCC_PCLK1Config(APB1_CFG); // APB1

		/* 启动PLL */
		RCC_PLLCmd(ENABLE);
		/* 等待PLL启动成功 */
		while(!RCC_GetFlagStatus(RCC_FLAG_PLLRDY)){}
		/* 配置PLL为系统时间 */
		RCC_SYSCLKConfig(PLLCLK);
}

然后我们只需要在main函式中初始化该API就可以调整系统时钟

#include "bsp_rccclkconfig.h"
#include "bsp_led.h"

int main(void)
{  
  HSE_SetSysCLK(SYSCLK_M,SYSCLK_N,SYSCLK_P,SYSCLK_Q);
  App_Init();  
  /* Infinite loop */
  while (1)
  {
	App_Thread();
  }
}

相关的marco定义如下所示:

#ifndef __RCCCLKCONFIG_H_
#define __RCCCLKCONFIG_H_

#include "stm32f4xx.h"

#define RCC_TEST 	 			0
#define SET_ON		 			1
#define TIMES	                100
#define HSE				 	    1
#define AHB_CFG 				1
#define APB2_CFG				4
#define APB1_CFG				5
#define PLLCLK					2

#define PLLM      			    25
#define PLLQ      			    9
#define PLLN     			    432
#define PLLP      			    0

#define SYSCLK_M   			    PLLM
#define SYSCLK_Q				PLLQ
#define SYSCLK_N  			    PLLN
#define SYSCLK_P				PLLP

extern void HSE_SetSysCLK(uint32_t m, uint32_t n, uint32_t p, uint32_t q);

#endif /*__RCCCLKCONFIG_H_*/

版权声明:本文为CSDN博主「zacch66」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_61825595/article/details/122643566

架构图

思考重点

  • 本文的目的是使用HSE外部晶振来配置系统时钟
  • 参考手册中的时钟树如何理解
  • 理解开发版初始化过程中对系统时钟的操作
  • 如何自行变更系统时钟

配置时钟源

在开发版STM32F429,以HSE, HSI, PLL作为主要的系统时钟的信号来源,并拥有LSI, LSE低速内外部信号时钟源,两者频率分别为32, 32.768kHz

时钟源相当于节拍器的功能,藉由稳定的信号源输出,可以有效配置出单位时间内系统的运算次数。下面探讨三个主要的系统时钟来源的功能与特色:

  • HSE
    • 高速外部时钟信号
    • 可由震盪器(oscillator)/晶振(crystal)提供信号源
    • 选择震盪器为信号源需要接上引脚OSC_OUT, OSC_IN
    • 频率: 4MHz~25MHz
  • HSI
    • 高速内部时钟信号
    • 内部晶振提供信号源
    • 当HSE故障将会自动切成HSI直到HSE恢復正常
    • 频率: 16MHz
  • PLL
    • 锁向环
    • 主要目的是对时钟信号源进行分频以及倍频处理,并将结果输出给相关外设
    • 开发版具有两个PLL,分别是主PLL和I2S专用PLLI2S
    • 官方建议最高运行频率为180MHz
    • 主PLL
      • 用于PLLCLK系统时钟
      • 用于USB OTG FS, RNG, SDIO时钟(48MHz)
    • PLLI2S
      • 用于I2S的时钟

时钟树

上图为reference manual中对设置系统时钟的描述,也就是着名的时钟树框图,由于我们的目标是配製系统时间SYSCLK,因此可以把主线任务从上图的红框部分拆分成以下的流程图,这样对接下来的程式范例也好理解

从图中我们可以发现配置系统时间过程中有两大重点

  1. 选择PLL时钟源
  2. 选择系统时钟源

而系统时间通常是使用HSE, HSI, PLL三者之一,可以透过配置暂存器来选择,一般来说系统时间会使用PLL倍频之后的结果

PLL倍频

由于外部时钟来源的频率不够大,开发版需要透过PLL锁向环,将输入时钟倍频成适合的系统频率。因此PLL的处理过程围绕在将时钟源切分成约1MHz后再进行放大,我们先来看看PLL系统时间的运算公式:

[(HSE/HSI)/分频因子M] * 倍频因子N / PLLCLK分频因子P

操作流程

  1. 选择时钟输入来源: HSE(25MHz)或HSI(16MHz)
  2. 设置分频因子M: 时钟源/M的结果务必在1~2MHz。M的范围: 2~63
  3. 设置倍频因子N : STM32F42xxx, STM32F43xxx系列频率范围: 192~432MHz
  4. 设置PLLCLK分频因子P: P可以是2、4、6、8

举例来说,我们选择25MHz的外部震盪器时钟源,透过将M配置成25,把V时钟输入结果配置成1MHz,然后把N设为360,将输出结果放大成360MHz,最后设置P为2,输出180MHz的PLL系统时钟源

另外假如PLL时钟来源选择HSE,当HSE发生问题时,系统会自动将时钟源切换成HSI

AHB外设时钟HCLK

当我们选择PLL作为系统时钟来源后,首先会输出到高速外设汇流排AHB,同样的我们可以透过软体控制暂存器的AHB分频因子,分频因子可以设置为1, 2, 4, 8, 16, 64, 128, 256, 512。几乎所有周边外设都使用AHB的系统时间频率

APB2外设时钟PCLK2

APB2汇流排时钟经由AHB时钟分频得到,可以透过软体操作暂存器的APB2分频因子,分频因子可以设置为1, 2, 4, 8, 16。需要注意APB2时钟频率不可以超过90MHz

APB1外设时钟PCLK1

APB1汇流排时钟经由AHB时钟分频得到,可以透过软体操作暂存器的APB1分频因子,分频因子可以设置为1, 2, 4, 8, 16。需要注意APB1时钟频率不可以超过45MHz

暂存器介绍

在接下来的系统时钟配置环节主要涉及以下几个暂存器,详细可以参考reference manual

RCC_CR

  • PLLRDY: 主PLL锁向环是否被开启
  • PLLON: 开启PLL锁向环
  • CSSON: 开启检测外部震盪器是否稳定
  • HSEBYP: 当HSE发生问题时bypass给其他时钟信号源
  • HSERDY: 由硬体判断HSE是否被开启
  • HSEON: 开启HSE时钟源
  • HSION: 开启HSI时钟源

RCC_PLLCFGR

  • PLLP: 配置分频因子P
  • PLLN: 配置分频因子N
  • PLLM: 配置分频因子M

RCC_CFGR

  • PPRE2: 配置APB2分频因子
  • PPRE1: 配置APB1分频因子
  • HPRE: 配置AHB分频因子
  • SWS: 等待硬体切换系统时钟来源
  • SW: 选择系统时钟来源

SetSysClock()函式

关于开发版初始化的主要写在函式SystemInit()当中,系统时钟的配置当然也不例外。在SystemInit() 我们可以找到SetSysClock()函式,我们上一小节介绍的诸如PLL时钟设定都在这个函式中完成,以下大致介绍SetSysClock():

  • 目的: 初始化系统时间
  • 主要操作:
    1. 开启HSE
    2. 配置内部电压调节器
    3. 配置AHB/APB1/APB2
    4. 配置PLL
    5. 开启PLL
    6. 开启Over-drive模式
    7. 配置Flash接口暂存器
    8. 将PLL配置成系统时间
static void SetSysClock(void)
{
  __IO uint32_t StartUpCounter = 0, HSEStatus = 0;
  
  /* 开启HSE,操作RCC_CR的HSEON位*/
  RCC->CR |= ((uint32_t)RCC_CR_HSEON);
 
  /* 在指定时间内等待硬体将HSERDY置位成1 */
  do
  {
    HSEStatus = RCC->CR & RCC_CR_HSERDY;
    StartUpCounter++;
  } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));

  /* 查看HSE是否配置成功,或者只是因为timeout退出 */
  if ((RCC->CR & RCC_CR_HSERDY) != RESET)
  {
    HSEStatus = (uint32_t)0x01; // HSE配置成功,将HSEStatus设为1
  }
  else
  {
    HSEStatus = (uint32_t)0x00; // HSE配置失败,将HSEStatus设为0
  }
  /* 若HSE配置成功,则可以开始系统时钟的处理流程 */
  if (HSEStatus == (uint32_t)0x01)
  {
    /* 配置内部电压调节器,以达到效率与功号之间的平衡 */
    RCC->APB1ENR |= RCC_APB1ENR_PWREN;
    PWR->CR |= PWR_CR_VOS;

    /* AHB分频因子配置成1 */
    RCC->CFGR |= RCC_CFGR_HPRE_DIV1;

    /* APB2分频因子配置成2 */
    RCC->CFGR |= RCC_CFGR_PPRE2_DIV2;
    
    /* APB1分频因子配置成4*/
    RCC->CFGR |= RCC_CFGR_PPRE1_DIV4;

    /* 配置RCC_PLLCFGR暂存器,我们主要关注M, N, P因子 */
    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-drive模式,使系统能够运行更高频率 */
    PWR->CR |= PWR_CR_ODEN;
		
	/* 等待Over-drive模式被成功开启 */
    while((PWR->CSR & PWR_CSR_ODRDY) == 0)
    {
    }
  
	/* 将系统切换为Over-drive模式 */	
    PWR->CR |= PWR_CR_ODSWEN;
		
	/* 等待系统成功切换置Over-drive模式 */		
    while((PWR->CSR & PWR_CSR_ODSWRDY) == 0)
    {
    } 
		
    /* 配置Flash接口暂存器 */
    FLASH->ACR = FLASH_ACR_PRFTEN | FLASH_ACR_ICEN |FLASH_ACR_DCEN |FLASH_ACR_LATENCY_5WS;

    /* 选择PLL作为系统时钟来源 */
    RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
    RCC->CFGR |= RCC_CFGR_SW_PLL;

    /* 等待硬体切换系统时钟来源 */
    while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS ) != RCC_CFGR_SWS_PLL);
    {
    }
  }
  else
  { /* 使用者可以自行定义若HSE启动失败要做那些处理 */
  }
}

超频处理

理解了SetSysClock()函式以后我们大致能掌握配置系统时间的操作,若我们想自行编写一个改变PLL系统时钟频率的API,可以简单地抓一下程式编写重点:

  1. 初始化RCC时钟配置成default状态
  2. 开启HSE
  3. 设置AHB/APB2/APB1分频因子
  4. 配置分频因子M, N, P
  5. 开启PLL
  6. 配置PLL为系统时钟来源

还记得在介绍倍频因子N的时候有提到STM32F42xxx, STM32F43xxx系列开发版可以将N设置到最大值432MHz吗?实际上官方参考手册虽建议最大频率为180MHz,不过还是预留空间供超频使用,因此我们希望透过自定义API将系统频率重新设置成216MHz

  • 关键点:
    • 在编写程式前可以先到标准库中阅读库函数
    • 搭配参考手册查阅暂存器设定
    • 参考SetSysClock()
  • 涉及库函式:
  1. RCC_DeInit(void)
  2. RCC_HSEConfig(uint8_t RCC_HSE)
  3. RCC_WaitForHSEStartUp(void)
  4. RCC_PLLConfig(uint32_t RCC_PLLSource, uint32_t PLLM, uint32_t PLLN, uint32_t PLLP, uint32_t PLLQ)
  5. RCC_HCLKConfig(uint32_t RCC_SYSCLK)
  6. RCC_PCLK2Config(uint32_t RCC_HCLK)
  7. RCC_PCLK1Config(uint32_t RCC_HCLK)
  8. RCC_PLLCmd(FunctionalState NewState)
  9. RCC_GetFlagStatus(uint8_t RCC_FLAG)
  10. RCC_SYSCLKConfig(uint32_t RCC_SYSCLKSource)

程式码范例

void My_Delay(__IO uint32_t count){
	for(;count > 0; count--);
}	

/**
 * vco range: 192~432Mhz
 * Re-set system clock by myself, the maximun frequency is 216Mhz
 * @param m Division factor
 * @param n Multiplication factor
 * @param p Division factor for main system clock
 * @param q Division factor for USB OTG FS, SDIO, etc.
 * @retval None
 */
void HSE_SetSysCLK(uint32_t m, uint32_t n, uint32_t p, uint32_t q){
		RCC_DeInit(); // 将RCC重置到预设模式
		RCC_HSEConfig(SET_ON); // 开启HSE

		/* 等待HSE启动成功 */
		while(!RCC_WaitForHSEStartUp()){
			My_Delay(TIMES);
			RCC_HSEConfig(SET_ON);
		}

		/* 配置PLL分倍频因子*/
		RCC_PLLConfig(HSE,m,n,p,q);
		/* 配置外设时钟分频因子*/
		RCC_HCLKConfig(AHB_CFG); // AHB
		RCC_PCLK2Config(APB2_CFG); // APB2
		RCC_PCLK1Config(APB1_CFG); // APB1

		/* 启动PLL */
		RCC_PLLCmd(ENABLE);
		/* 等待PLL启动成功 */
		while(!RCC_GetFlagStatus(RCC_FLAG_PLLRDY)){}
		/* 配置PLL为系统时间 */
		RCC_SYSCLKConfig(PLLCLK);
}

然后我们只需要在main函式中初始化该API就可以调整系统时钟

#include "bsp_rccclkconfig.h"
#include "bsp_led.h"

int main(void)
{  
  HSE_SetSysCLK(SYSCLK_M,SYSCLK_N,SYSCLK_P,SYSCLK_Q);
  App_Init();  
  /* Infinite loop */
  while (1)
  {
	App_Thread();
  }
}

相关的marco定义如下所示:

#ifndef __RCCCLKCONFIG_H_
#define __RCCCLKCONFIG_H_

#include "stm32f4xx.h"

#define RCC_TEST 	 			0
#define SET_ON		 			1
#define TIMES	                100
#define HSE				 	    1
#define AHB_CFG 				1
#define APB2_CFG				4
#define APB1_CFG				5
#define PLLCLK					2

#define PLLM      			    25
#define PLLQ      			    9
#define PLLN     			    432
#define PLLP      			    0

#define SYSCLK_M   			    PLLM
#define SYSCLK_Q				PLLQ
#define SYSCLK_N  			    PLLN
#define SYSCLK_P				PLLP

extern void HSE_SetSysCLK(uint32_t m, uint32_t n, uint32_t p, uint32_t q);

#endif /*__RCCCLKCONFIG_H_*/

版权声明:本文为CSDN博主「zacch66」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_61825595/article/details/122643566

生成海报
点赞 0

zacch66

我还没有学会写个人说明!

暂无评论

发表评论

相关推荐

STM32开发笔记04---配置系统时间

架构图 思考重点 本文的目的是使用HSE外部晶振来配置系统时钟参考手册中的时钟树如何理解理解开发版初始化过程中对系统时钟的操作如何自行变更系统时钟 配置时钟源 在开发版STM32F429,以HSE, HSI, PLL作为主要

ESP32S2+ES8388移植过程及问题

电路图如下, 有点小瑕疵ES8388_VMID PIN10/19/20电容没有忘加,查资料应该不影响语言输出,可能噪音大,如果能导致不输出请告诉我一下。 ESP32S2管脚映射 这里主

四足机器狗——12自由度舵机狗DIY(一)

文章目录 前言 一、初步了解四足结构 1.1.2串联机构 1.2 四足关节配置 二、结构方案选择及舵机选型 2.1并联与串联机构的选型 2.2 四足关节配置的选择 2.3 电机选型(有经济基础的建议尝试) 2.4 舵