STM32 时钟配置之寄存器操作

1 时钟

1.1时钟树

Stm32 的时钟配置必须要参考时钟树,时钟树决定了时钟的配置的路径,兼着参考RCC寄存器就可以配置不同的时钟频率了。另外STM32外部晶振推荐为8M,所以用外部时钟时最好采用推荐值。

1.2 时钟配置

程序刚启动的时候,stm32采用的为内部高速时钟,通过上图的时钟树可以发现内部8M时钟通过SW成为系统时钟。RCC_CR的复位值为0x000XX83,展开后为HSION1,也印证了时钟默认为内部高速时钟。如果需要采用外部时钟,需要按照如下的方式配置。

1、时钟初始化,即将时钟的寄存器采用默认值。

2、开始外部时钟且外部时钟起震准备就绪。

3、设置PLLXTPRE只能在关闭PLL时才能写入此位),可选择分频不分频。

4、设置进入PLL的源时钟(只能在关闭PLL时才能写入此位)。因为采用外部时钟所以只有一种设置。

5、设置PLL倍频系数PLLMUL只有在PLL关闭的情况下才可被写入)。

6、开启PLL,且准备就绪。

7、设置SW,选择时钟源为系统时钟。

8、判断是否是预选的时钟为系统时钟。

注:必须在使能每个PLL之前完成PLL的配置(选择时钟源、预分频系数和倍频系数等),同时应该在它们的输入时钟稳定(就绪位)后才能使能。一旦使能了PLL,这些参数将不能再被改变。AHB,APB1APB2。只要系统时钟确定了,他们就确定了,但是和系统是几分频需要在系统时钟开启前设置好,这个是设置项,并不是开启项。另外,由于FASH取指用的是AHB的频率,在采用不同的系统频率时,在时钟配置的时候需要延时。这里需要参考stm32FLASH编程手册。在开启PLL时钟之前需要设置FLASH->ACR|=0x32;目的是flash的取指的稳定性需要和系统时钟构成某种关系。

1.3程序实现

如上,外部晶振为8M,系统时钟为72M的配置程序如下。

/*

@brife:this is source file for system clock

@editor:houchao

*/

#include"stm32f10x.h"

#include"System_Clock.h"

voidRCC_DeInit()

{

         RCC->APB1RSTR&=(uint32_t)0x00000000;//

         RCC->APB2RSTR&=(uint32_t)0X00000000;//

         RCC->AHBENR&=(uint32_t)0x00000014;//

         RCC->APB1ENR&=(uint32_t)0x00000000;//

         RCC->APB2ENR&=(uint32_t)0x00000000;//

         RCC->CR|=0X00000001;//

        while(0==((RCC->CR>>1) &0x00000001));

        RCC->CFGR&=(uint32_t)0XFFFFFFFE;//

        while((RCC->CFGR>>2)!=1&&(RCC->CFGR>>3)==1);//

        RCC->CIR&=(uint32_t)0x00000000;//

}

 

/*

@brife:

@editor£ºhouchao

*/

voidsystem_clock(void)

{

         RCC_DeInit();

     

         RCC->CR |= (uint32_t) 0X00010000;


         while(0==((RCC->CR>>17)&0x00000001));

         //APB1=DIV2;APB2=DIV1;AHB=DIV1;

         RCC->CFGR=0X00000400;

        RCC->CFGR &=0xfffeffff;

        RCC->CFGR |=0x00007000;

        RCC->CFGR|=7<<18;//

         FLASH->ACR|=0x32;       //FLASH 2

         RCC->CR|=0x01000000;  //PLLON

         while(!(RCC->CR>>25));//

         RCC->CFGR|=0x00000002;//

         while(((RCC->CFGR>>2)&0x03)!=0x02);//

        

        

}

如上的程序在调试的过程中,发现程序下载后,单片机无法启动,经过排查程序出现在

while((RCC->CFGR>>2)!=1&&(RCC->CFGR>>3)==1);//确定内部时钟为高速时钟

当判断为 (RCC->CFGR>>2)!=1&&(RCC->CFGR>>3)==0时,程序无法跳出该语句。

该语句目的是保证单片机工作在内部时钟的频率下,仔细一看,不对呀,这条语句搞的太复杂了吧,于是化简如下:

while(((RCC->CFGR>>2)& 0x03 )!=0x00); 通过LED灯闪烁的频率证明,mcu的时钟发生切换,现在又存在另外一个问题,我们切换后的时钟,系统时钟到底是以多少的频率在跑呢?看到这里,我们发现该单片机能够将系统时钟通过配置输出到特定的单片机管脚,我们配置后,通过示波器看该管脚的波形,就知道了我们设置的系统时钟是否是我们预想的结果。该实验将在后面推出,敬请关注。另外编译器复制过来的代码注释有乱码,目前还没有解决,抱歉。

加油,释放你的创造力!!!

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值