STM32F407:SystemInit时钟系统初始化函数

本身F4时钟树就是够枯燥的了,配置时钟树的库函数初始化就更枯燥了,我看了4遍网课了已经,看一遍睡着一遍,故我将视频中内容一一分析,总结如下:

时钟系统初始化函数只有在库函数版本中才有 。

  1. 执行程序之前必先驱动时钟

从以下代码中可以看出在运行主函数之前要先初始化时钟系统函数

Reset_Handler    PROC
                 EXPORT  Reset_Handler             [WEAK]
        IMPORT  SystemInit   //先输出
        IMPORT  __main        //后输出

                 LDR     R0, =SystemInit
                 BLX     R0
                 LDR     R0, =__main
                 BX      R0
                 ENDP
  1. 初始化系统时钟函数
void SystemInit(void)
{
  /* FPU settings ------------------------------------------------------------*/
  #if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
    SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2));  /* set CP10 and CP11 Full Access */
  #endif
  /* Reset the RCC clock configuration to the default reset state ------------*/
  /* Set置位 HSION bit */
  RCC->CR |= (uint32_t)0x00000001;
  //将CR寄存器第一位(位0,如下第一图所示)设置为1,打开HSI振荡器。


  /* Reset复位¸´Î» CFGR register */
  RCC->CFGR = 0x00000000;//全复位了

  /* Reset HSEON, * *ON and PLLON bits */
  RCC->CR &= (uint32_t)0xFEF6FFFF;  
  //将16进制值用二进制来表示1111 1110 1111 0110 1111 1111 1111 1111 ,
  //可以看出第16,19,24位置0(如下第二三四图)。
  //HSE 振荡器关闭,时钟安全系统关闭,主PLL关闭

  /* Reset PLLCFGR register */
  RCC->PLLCFGR = 0x24003010;
  //0010 0100 0000 0000 0011 0000 0001 0000
  //位5:0设置PLLM=32分频(2~63),位14:6主PLL倍频系数PLLN=192(范围是192~432),位17:16 PLLP=2,
  //位21:18保留,必须保持复位值,位22选择HSE作为PLL输入,位23位保留,位27:24 PLLQ=4,位31:28,
  //保持复位值。
  /* Reset HSEBYP bit */
  RCC->CR &= (uint32_t)0xFFFBFFFF;
  //同理1011是将第3位置零也就是第18位置零,外部时钟旁路HSE振荡器
  

  /* Disable all interrupts */
  RCC->CIR = 0x00000000;
  • 以下图片均为CR时钟控制寄存器的位控制图。


在这里插入图片描述
在这里插入图片描述
时钟安全系统(CSS)作用: 当主PLL选择HSE作为时钟来源时(如下图),假如OSC_IN挂掉了导致没有时钟输入,那么时钟安全系统就会识别到PLLCLK状态不行,主动将SYSCLK的时钟来源选择切换为HSI状态,保证外设系统执行 。
在这里插入图片描述

在这里插入图片描述
在里插入图片描述

  1. SetSysClock()函数
static void SetSysClock(void)
RCC->CR |= ((uint32_t)RCC_CR_HSEON);//使能第16位HSE
do
  {
    HSEStatus = RCC->CR & RCC_CR_HSERDY;
    StartUpCounter++;
  } while((HSEStatus ==  0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
  //等待第17位返回1(就绪),正式开启。若长时间不返回一 系统也会自行中断向下走。CR等待函数
 if (HSEStatus == (uint32_t)0x01)
  {
    /* 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;   //不分频 使得HCLK等于SYSCLK

#if defined (STM32F40_41xxx) || defined (STM32F427_437xx) || defined (STM32F429_439xx)      
    /* PCLK2 = HCLK / 2*/
    RCC->CFGR |= RCC_CFGR_PPRE2_DIV2;  // 设置APB2二分频
    /* PCLK1 = HCLK / 4*/
    RCC->CFGR |= RCC_CFGR_PPRE1_DIV4;//设置APB1四分频
#endif /* STM32F40_41xxx || STM32F427_437x || STM32F429_439xx */

 /* Configure the main PLL */
    RCC->PLLCFGR = PLL_M | (PLL_N << 6) | (((PLL_P >> 1) -1) << 16) |
                   (RCC_PLLCFGR_PLLSRC_HSE) | (PLL_Q << 24);
                   //使能PLLCFGR各个参数(N、P、M、Q)值进行算数

    /* Enable the main PLL */
    RCC->CR |= RCC_CR_PLLON;  //使能主PLL

    /* Wait till the main PLL is ready */
    while((RCC->CR & RCC_CR_PLLRDY) == 0)//等待主PLL就绪
    {
    }
  /* Select the main PLL as system clock source */
    RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
    RCC->CFGR |= RCC_CFGR_SW_PLL;  //系统时钟时钟源的切换!! 选择PLLCLK作为其时钟源

    /* Wait till the main PLL is used as system clock source */
    while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS ) != RCC_CFGR_SWS_PLL);
    {
    }

到这里 我们配置了 HCLK、PCLK2、PCLK1、选择HSE作为PLL时钟源,配置了PLLCLK(PLLCFGR)并等待就绪,又把系统时钟设置为PLLCLK(CFGR)并等待就绪。

  1. 总结
    结合时钟树总结配置全过程在这里插入图片描述

①打开HSE时钟等待其使能
②配置好HCLK、APB1、APB2外设时钟跟系统时钟关系。
③将HSE设置为主PLL的时钟源
④配置好M、N、P值,使能PLLCLK并等待其就绪
⑤将系统时钟选择PLLCLK作为其时钟源,最后达到配置系统时钟作用

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值