STM32F407标准库学习笔记-RCC机制

在这里插入图片描述

机制分析

上电后默认使用的是内部的HSI,一般工作在8MHz,且准度不可靠,标准库会调用启动代码和system_stm32f4xx.h/system_stm32f4xx.c中的相关函数将系统时钟选为HSE+PLL 168MHz。注意,若你没有使用标准库,而是在KEIL的 运行时环境设置 界面选择添加的 CORE和S文件,则不会切换时钟(不包含相关函数),而是默认使用HSI。

使用HSE和PLL的时钟路径如上图所示;
1.启动HSE,外部晶振结合内部电路起振,输出HSE时钟信号。
2.将PLL输入信号选为HSE。
3.HSE除以M后,输入PLL,应在1~2MHz之间,常用1MHz;注意,相关设置函数的注释中建议使用2MHz,理由是此时PLL的准确度会最好,但在实际使用中会导致后面的信号频率超出限制范围。
4.上一步的结果乘N=VCO,注意VCO也有范围要求,VCO/P=PLLCLK最大168MHz(更高会不稳定)。
5.启动PLL,等待PLL起振,工作稳定。
6.设置后续的AHB与APB总线频率(HCLK/PCLK),影响内核工作频率和外设频率等。
7.将PLLCLK选作SYSCLK,设置完成。
注意:在实际设置中,还会设置电源、FLASH相关寄存器,以使得时钟设置生效且能正常读写内存,后面有介绍。

代码分析

-stm32f4xx.h

#if defined(STM32F40_41xxx)
 #if !defined  (HSE_VALUE) 
  #define HSE_VALUE    ((uint32_t)25000000) /*!< Value of the External oscillator in Hz */
HSE_VALUE应该等于开发板上外部晶振的工作频率,后面的程序会用到这个值进行计算,务必修改正确;
标准库默认值为25MHz,我个人所用为8MHz,应修改为8000000.
  • system_stm32f4xx.c
#if defined(STM32F40_41xxx) 
 /* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N */
 #define PLL_M      25

#if defined (STM32F40_41xxx)
#define PLL_N      336
/* SYSCLK = PLL_VCO / PLL_P */
#define PLL_P      2
#endif /* STM32F40_41xxx */
用于确定M N P的值,设置PLL,修改时要注意每一步的频率限制和倍数限制。
具体参考手册6.3.2.
SystemInit_ExtMemCtl(void);
使用外置存储器是需要使用的函数,暂时不理会。
SystemInit(void)
系统初始化,主要是将RCC相关寄存器设为复位值,再调用时钟设置函数,完成任务。
SetSysClock();
主要的时钟设置操作都在里面,实现前面机制分析中的过程
 /* Enable HSE */
  RCC->CR |= ((uint32_t)RCC_CR_HSEON);
 
  /* Wait till HSE is ready and if Time out is reached exit */
  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;
  }

  if (HSEStatus == (uint32_t)0x01)
启动HSE,并等待和判断它工作正常。
/* Select regulator voltage output Scale 1 mode */
    RCC->APB1ENR |= RCC_APB1ENR_PWREN;
    PWR->CR |= PWR_CR_VOS;
    /* 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;
先选择了电源模块的工作模式,后修改了总线的分频系数。
参考手册5.1.3
	运行模式,调压器为 1.2 V 域(内核、存储器和数字外设)提供全功率。在此模式下,
	调压器的输出电压(约 1.2 V)可通过软件调整为不同的电压值:
	— 对于 STM32F405xx/07xx 和 STM32F415xx/17xx
	可通过 VOS(PWR_CR 寄存器的位 15)动态配置成级别 1 或级别 2。
参考手册3.4.1
	注意:STM32F405xx/07xx 和 STM32F415xx/17xx 器件:
	当 VOS =“0”时,fHCLK 最大值 = 144 MHz。
	当 VOS =“1”时,fHCLK 最大值 = 168 MHz。
#if defined(STM32F40_41xxx) 
    /* Configure the main PLL */
    RCC->PLLCFGR = PLL_M | (PLL_N << 6) | (((PLL_P >> 1) -1) << 16) |
                   (RCC_PLLCFGR_PLLSRC_HSE) | (PLL_Q << 24);
#endif
  /* Enable the main PLL */
    RCC->CR |= RCC_CR_PLLON;

    /* Wait till the main PLL is ready */
    while((RCC->CR & RCC_CR_PLLRDY) == 0)
    {
    }
设置PLL相关参数,并启动,等待正常
#if defined(STM32F40_41xxx)  || defined(STM32F412xG)  
    /* Configure Flash prefetch, Instruction cache, Data cache and wait state */
    FLASH->ACR = FLASH_ACR_PRFTEN | FLASH_ACR_ICEN |FLASH_ACR_DCEN |FLASH_ACR_LATENCY_5WS;
#endif /* STM32F40_41xxx  || STM32F412xG */
修改FLASH存取控制寄存器
参考手册3.4.1中有表格参考。
/* Select the main PLL as system clock source */
    RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
    RCC->CFGR |= RCC_CFGR_SW_PLL;

    /* Wait till the main PLL is used as system clock source */
    while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS ) != RCC_CFGR_SWS_PLL);
    {
    }
将PLLCLK切换为系统时钟,并等待成功。

最后发现,在相关函数中,默认使用HSE和PLL的组合,没有使用RCC.c和.h中的任何代码,所以想要使用其他时钟设置的话,需要自己写代码,使用c h 文件可以帮助你;同时,在不借助标准外设库代码的情况下,以上三个文件也可以正常使用。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值