STM32 RCC配置过程学习笔记

STM32时钟系统示意图

请添加图片描述

时钟源主要有

  1. HSI 内部高速RC振荡时钟,约为8M
  2. HSE 外接晶振,例如8M石英晶振
  3. PLL 锁相环,可以倍频(2到16倍)
  4. LSE 外部低速晶振,如32.768KHz
  5. LSI 内部低速RC振荡时钟,约为40KHz

其他相关部分

  1. CSS 时钟检测系统,当外部时钟不正常工作时,自动切换为内部时钟
  2. MCO 内部时钟输出接口
  3. AHB 分频器
  4. APB1\APB2 分频器

RCC寄存器相关部分

主要寄存器
对应寄存器每个位置的控制信息可以看芯片手册查询。

  1. CR 控制寄存器
  2. OFCR 配置寄存器
  3. CIR 中断寄存器
  4. AHBENR 使能寄存器
  5. APB1ENR (低速外设)
  6. APB2ENR (高速外设)
  7. APB1RSTR 复位寄存器
  8. APB2RSTR
  9. BDCR 备份域寄存器
  10. CSR 控制、状态寄存器

分析SystemInit函数

void SystemInit (void)//来源标准库便于理解有删减,详细请去标准库查看
{
  /* 修改CR打开HSI*/
  RCC->CR |= (uint32_t)0x00000001;

  /* 设置 SW, HPRE, PPRE1, PPRE2, ADCPRE and MCO bits */
  RCC->CFGR &= (uint32_t)0xF0FF0000;
  
  
  /* 设置 HSEON, CSSON and PLLON bits */
  RCC->CR &= (uint32_t)0xFEF6FFFF;

  /* 设置 HSEBYP bit */
  RCC->CR &= (uint32_t)0xFFFBFFFF;

  /* 设置 PLLSRC, PLLXTPRE, PLLMUL and USBPRE/OTGFSPRE bits */
  RCC->CFGR &= (uint32_t)0xFF80FFFF;
  /*中断关闭*/
  RCC->CIR = 0x009F0000;



  /* 系统时钟配置 */
  SetSysClock();

  SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; 
}

SetSysClock相关:

static void SetSysClock(void)
{
#ifdef SYSCLK_FREQ_HSE
  SetSysClockToHSE();
#elif defined SYSCLK_FREQ_24MHz
  SetSysClockTo24();
#elif defined SYSCLK_FREQ_36MHz
  SetSysClockTo36();
#elif defined SYSCLK_FREQ_48MHz
  SetSysClockTo48();
#elif defined SYSCLK_FREQ_56MHz
  SetSysClockTo56();  
#elif defined SYSCLK_FREQ_72MHz
  SetSysClockTo72();
#endif
 
 /* 通过定义频率的相关变量来决定调用哪个函数 */ 
}

假设我们定义了SYSCLK_FREQ_72MHz,下面看看SetSysClockTo72()函数:

static void SetSysClockTo72(void)
{
  __IO uint32_t StartUpCounter = 0, HSEStatus = 0;
  
  /* SYSCLK, HCLK, PCLK2 and PCLK1 configuration ---------------------------*/    
  /* 使能 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;
  }  

  if (HSEStatus == (uint32_t)0x01)
  {
    /* Enable Prefetch Buffer */
    FLASH->ACR |= FLASH_ACR_PRFTBE;

    /*等待FLASH */
    FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY);
    FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_2;    

 
    /*配置 HCLK = SYSCLK */
    RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;
      
    /* 配置PCLK2 = HCLK */
    RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1;
    
    /* 配置PCLK1 = HCLK */
    RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2;

    
    /*  PLL锁相环输出配置: PLLCLK = HSE * 9 = 72 MHz */
    RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE |
                                        RCC_CFGR_PLLMULL));
    RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLMULL9);
#endif /* STM32F10X_CL */

    /* 使能PLL */
    RCC->CR |= RCC_CR_PLLON;

    /* 等待 PLL 稳定 */
    while((RCC->CR & RCC_CR_PLLRDY) == 0)
    {
    }
    
    /* 把PLLCLK设置为系统时钟 */
    RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
    RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL;    

    /* 等待稳定 */
    while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x08)
    {
    }
  }
  else
  { /* If HSE fails to start-up, the application will have wrong clock 
         configuration. User can add here some code to deal with this error */
  }
}
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值