当前位置:   article > 正文

(STM32笔记)九、RCC时钟树与时钟 第二部分

(STM32笔记)九、RCC时钟树与时钟 第二部分

我用的是正点的STM32F103来进行学习,板子和教程是野火指南者
之后的这个系列笔记开头未标明的话,用的也是这个板子和教程。

九、RCC时钟树与时钟

2、时钟配置函数

在程序启动文件startup_stm32f10x_hd.s里找到SystemInit函数跳转入口
在这里插入图片描述

system_stm32f10x.c中找到SystemInit函数

时钟初始化思路(72M)

复位时钟至默认状态
    RCC->CR   |= (u32)0x00000001;                                // 开启内部时钟
    RCC->CFGR &= (u32)0xF8FF0000;                                // 复位 SW, HPRE, PPRE1, PPRE2, ADCPRE and MCO bits
    RCC->CFGR &= (u32)0xFF80FFFF;                                // 复位 PLL和分频的配置
    RCC->CIR   = 0x009F0000;                                     // 关闭中断,清理中断位
  • 1
  • 2
  • 3
  • 4
使能HSE,并等待HSE就绪
// 配置时钟 HCLK, PCLK, PCLK1, PCLK2, FLASH 
    __IO u32 StartUpCounter = 0, HSEStatus = 0;      
    
    RCC->CR |= ((u32)RCC_CR_HSEON);                              // 使能 HSE  
    do{                                                          // 等待HSE就绪
        HSEStatus = RCC->CR & RCC_CR_HSERDY;
        StartUpCounter++;  
      } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));   // 0x0500
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
设置flash,设置时钟树,使能PLL
    if ((RCC->CR & RCC_CR_HSERDY) != RESET)  {  
        FLASH->ACR |= FLASH_ACR_PRFTBE;                          // 启动预取缓冲区   
        FLASH->ACR &= (u32)((u32)~FLASH_ACR_LATENCY);            // 设置时延
        FLASH->ACR |= (u32)FLASH_ACR_LATENCY_2;    
 
        RCC->CFGR  |= (u32)RCC_CFGR_HPRE_DIV1;                   // [7:4]   AHB  预分频, HCLK = SYSCLK/1  不分频     
        RCC->CFGR  |= (u32)RCC_CFGR_PPRE2_DIV1;                  // [13:11] APB2 预分频, APB2 = HCLK/1,   不分频
        RCC->CFGR  |= (u32)RCC_CFGR_PPRE1_DIV2;                  // [10: 8] APB1 预分频, APB1 = HCLK/2,    2分频
 
        RCC->CFGR  &= (u32)(~( 1<<16 | 0x01<<17 | 0xF<<18));     // 清零
        RCC->CFGR  |= (u32)(0x01<<16 | 0x07<<18);                // PLL 时钟源,低频因子,倍频系数, 使PLLCK= HSE * 9= 72MHz   
        RCC->CR    |= (u32)(0x01<<24);                           // 使能PLL    
        while((RCC->CR & RCC_CR_PLLRDY) == 0) {  }               // 等待PLL就绪
    
        RCC->CFGR &= (u32)((u32)~(0x3<<0));                      // 清0
        RCC->CFGR |= (u32)(0x1 << 1);                            // 切换系统时钟源为:PLLCLOCK    
        while ((RCC->CFGR & (u32)RCC_CFGR_SWS) != (u32)0x08) { } // 等待系统时钟切换完成
    }
    else
    { 
        // 重要!!!
        // 时钟初始化失败 
        // 处理位置
    }    
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

更新时钟频率思路

获取时钟源
    u32 tmp = 0, pllmull = 0, pllsource = 0;    
 
    tmp = RCC->CFGR & RCC_CFGR_SWS;                                 // 获取时钟源
  • 1
  • 2
  • 3
选择系统时间源
switch (tmp)  {
        case 0x00:                                                  // HSI 内部高速晶振 被选为系统时钟源
            SystemCoreClock = HSI_VALUE;
            break;
    
        case 0x04:                                                  // HSE 外部高速晶振 被选为系统时钟源
            SystemCoreClock = HSE_VALUE;
            break;
    
        case 0x08:                                                  // PLL 被先为系统时钟源     
            pllmull = RCC->CFGR & RCC_CFGR_PLLMULL;                 // PLL 时钟源及倍频系数
            pllsource = RCC->CFGR & RCC_CFGR_PLLSRC;       
            pllmull = ( pllmull >> 18) + 2;      
            if (pllsource == 0x00)
            {        
                SystemCoreClock = (HSI_VALUE >> 1) * pllmull;       // HSI振荡器时钟2分频作为PLL时钟输入
            }
            else
            {                                                       // HSE作为PLL时钟输入                              
                if ((RCC->CFGR & RCC_CFGR_PLLXTPRE) != (u32)RESET)
                {
                    SystemCoreClock = (HSE_VALUE >> 1) * pllmull;   // HSE 2分频
                }
                else
                {
                    SystemCoreClock = HSE_VALUE * pllmull;
                }
            }
            break;
 
        default:
            SystemCoreClock = HSI_VALUE;
            break;
    } 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
保存在SystemCoreClock
    tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> 4)];  
    SystemCoreClock >>= tmp; 
  • 1
  • 2
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/木道寻08/article/detail/936137
推荐阅读
相关标签
  

闽ICP备14008679号