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

我用的是正点的STM32F103来进行学习,板子和教程是野火的指南者

之后的这个系列笔记开头未标明的话,用的也是这个板子和教程。

九、RCC时钟树与时钟

九、RCC时钟树与时钟

2、时钟配置函数

在程序启动文件startup_stm32f10x_hd.s里找到SystemInit函数跳转入口

system_stm32f10x.c中找到SystemInit函数

时钟初始化思路(72M)

复位时钟至默认状态
c 复制代码
    RCC->CR   |= (u32)0x00000001;                                // 开启内部时钟
    RCC->CFGR &= (u32)0xF8FF0000;                                // 复位 SW, HPRE, PPRE1, PPRE2, ADCPRE and MCO bits
    RCC->CFGR &= (u32)0xFF80FFFF;                                // 复位 PLL和分频的配置
    RCC->CIR   = 0x009F0000;                                     // 关闭中断,清理中断位
使能HSE,并等待HSE就绪
c 复制代码
// 配置时钟 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
设置flash,设置时钟树,使能PLL
c 复制代码
    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
    { 
        // 重要!!!
        // 时钟初始化失败 
        // 处理位置
    }    

更新时钟频率思路

获取时钟源
c 复制代码
    u32 tmp = 0, pllmull = 0, pllsource = 0;    
 
    tmp = RCC->CFGR & RCC_CFGR_SWS;                                 // 获取时钟源
选择系统时间源
c 复制代码
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;
    } 
保存在SystemCoreClock
c 复制代码
    tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> 4)];  
    SystemCoreClock >>= tmp; 
相关推荐
Zevalin爱灰灰39 分钟前
编程技巧(基于STM32)第一章 定时器实现非阻塞式程序——按键控制LED灯闪烁模式
stm32·单片机·嵌入式硬件
饮长安千年月2 小时前
Linksys WRT54G路由器溢出漏洞分析–运行环境修复
网络·物联网·学习·安全·机器学习
红花与香菇2____2 小时前
【学习笔记】Cadence电子设计全流程(二)原理图库的创建与设计(上)
笔记·嵌入式硬件·学习·pcb设计·cadence·pcb工艺
Jerry.yl3 小时前
关于 BK3633 上电时受串口 UART2 影响而无法启动的问题说明
嵌入式硬件·物联网·bk3633
苏慕TRYACE4 小时前
RT-Thread+STM32L475VET6实现红外遥控实验
stm32·单片机·嵌入式硬件·rt-thread
一天八小时4 小时前
Docker学习进阶
学习·docker·容器
前端没钱4 小时前
前端需要学习 Docker 吗?
前端·学习·docker
拥有一颗学徒的心5 小时前
鸿蒙第三方库MMKV源码学习笔记
笔记·学习·性能优化·harmonyos
车端域控测试工程师5 小时前
【ISO 14229-1:2023 UDS诊断(ECU复位0x11服务)测试用例CAPL代码全解析⑰】
经验分享·学习·汽车·测试用例·capl
车端域控测试工程师5 小时前
【ISO 14229-1:2023 UDS诊断(ECU复位0x11服务)测试用例CAPL代码全解析⑪】
经验分享·学习·汽车·测试用例·capl