• STM32的时钟配置随笔


      以前使用STM32都是使用库函数开发,最近心血来潮想要使用寄存器来试试手感,于是乎便在工作之余研究了一下STM32F4的时钟配置,在此将经历过程写下来作为锻炼,同时也供和我一样的新手参考,如有错误或者更好的方法欢迎大家批评指正。

            

                       从技术文档上得到STM32时钟源有三种, HSI 振荡器时钟 、HSE 振荡器时钟 、主 PLL时钟,由于每个时钟的工作特性的差异,若想将系统时钟设置为最高频时需使用PLL将基础时钟源进行倍频。

    由于使用外部晶振倍频精确度会比内部震荡时钟高很多,所以一般都是使用外部晶振,这跟我们使用库开发是一样的原理,所以一般的配置关键点大概如下图红框所示:

                       

    1、第一步首先要将外部HSE时钟打开,等待震荡稳定后再进行下一步操作。

    2、配置PLL寄存器参数。

    3、切换系统时钟源。

    第一步实现:

    依据:

              开启HSE时钟源主要是控制CR寄存器的16位,然后打开后硬件会自动将第17位置位,如果未成功则等待,当然在这个地方可以加入时间等待,如果超时说明打开失败,进行其他方法设置。

              实现:

              

    第二步实现:

     依据:

              

    在这里技术文档上说明了各个参数的设置范围:

     2 ≤ PLLQ  ≤ 15 、 PLLP = 2、4、6 或 8、 192 ≤ PLLN ≤ 432 、 2 ≤ PLLM ≤  63

    由于我想将STM32设置成最高频168M,于是根据以上参数范围以及计算方法,选择一组设置参数如下:

    PLL_M = 8,PLL_N  = 336,PLL_P  =  1  (2分频),PLLQ  =  7;

    参数确定便可以直接设置,这些位只能在 PLL 已禁止时写入。

    实现:在这里记录一下自己的小心得,以前配置寄存器都是将要配置的数先算出来,耽误时间,今天在看技术文档时突然发现直接用移位即可,且为提高代码的可读性,最好是选用或运算单个设置每个设置点。这样看起来就舒服多了。

    第三步实现:

     依据:

    这个时候就需要将系统时钟切换过来了,主要是设置SW开关,然后再设置AHB、APB1、APB2、等时钟,在上时钟树上可看出。

    还是操作对应的位,在这里又发现一个小技巧,原来STM32系统头文件已经做好这些设置的宏定义,直接使用即可,而且从可读性来说大大加强,如下图所示。最后将设置好的时钟通过MCO1输出,检测。

    实现:

    整个时钟就到此配置结束,原以为会梦想成真,可实际却发现不尽人意,为啥波形没有呢,苦思冥想了很长时间,最后参考库函数底层实现方式,加了一句:

    然后就完美输出,在这里我不是很理解为什么要添加这句,以前用msp430的时候好像也没这个设置,而且我发现光设置CPU等待周期还不行,还得设置前面两个参数,不然设置的时钟偏差很大。

    实际设置函数如下所示:

     1 void SystemClockInit(void)
     2 {
     3     
     4    RCC->CR |= RCC_CR_HSEON;
     5    while(!(RCC->CR & RCC_CR_HSERDY)){}
     6     
     7    RCC->CR &= ~RCC_CR_PLLON;   
     8    RCC->PLLCFGR = 0x00000000;
     9    //PLL_M = 8,PLL_N = 336,PLL_P = 1  (2分频)
    10    RCC->PLLCFGR |= 8 << 0;   
    11    RCC->PLLCFGR |= 336 << 6;   
    12    RCC->PLLCFGR |= 1 << 16;  
    13  
    14    RCC->PLLCFGR |= 7 << 24;    //配置PLLQ为48M   
    15    RCC->CR |= RCC_CR_PLLON;  
    16 
    17    while(!(RCC->CR & RCC_CR_PLLRDY)){}
    18        
    19    FLASH->ACR = FLASH_ACR_ICEN | FLASH_ACR_DCEN | FLASH_ACR_LATENCY_5WS;
    20      
    21    RCC->CFGR |= RCC_CFGR_HPRE_DIV1;   //不分频使AHB时钟为168M
    22    RCC->CFGR |= RCC_CFGR_PPRE2_DIV2;  //APB2 = 84M
    23    RCC->CFGR |= RCC_CFGR_PPRE1_DIV4;  //APB1 = 42M   
    24  
    25    RCC->CFGR |= RCC_CFGR_SWS_PLL;
    26    RCC->CFGR |= RCC_CFGR_SW_PLL;
    27          
    28    RCC->CFGR |= 3 << 21;    //PLL输出
    29    RCC->CFGR |= 4 << 24;    // 2分频     
    30   
    31 }

    最后两分频的波形显示如下:

    到此配置就结束了,留有一个问题,那就是STM32时钟配置为啥要配置那个CPU等待周期,也就是这条语句:

     

     欢迎大神不吝赐教,下方留言解答,万分感谢。

  • 相关阅读:
    写给刚接触Active Directory的朋友(转)
    vim中缩进的设置以及将tab转换成空格
    Ubuntu12.04 更新源
    实验三电子公文传输系统1个人贡献
    20191325实验四 Web服务器1socket编程
    20191325学习笔记10
    OpenEuler 中C与汇编的混合编程
    20191325第十三章学习笔记
    20191323第十四章学习笔记
    http 三次握手 四次挥手,面试题
  • 原文地址:https://www.cnblogs.com/wangshucai/p/9458109.html
Copyright © 2020-2023  润新知