stm32学习2:系统时钟

STM32学习2:系统时钟介绍与配置


  鄙人是在淘宝购置了一套STM32开发板,跟着随带的光盘学习起来的。碰到不懂的就在CSDN上浏览学习高手的博客,大神们不仅技术很好还乐于分享,蒙其惠泽,未感忘恩,所以自己开始写博客慢慢积累。
  如果您是初学者,看到该系列文章后有所帮助,鄙人深感荣幸。如果您是大神,请您指出不足指出。如果没人看到,权当积累与记录了。
  鄙人使用普中科技公司的开发板,在淘宝可以找到。芯片是STM32F103ZET6,固件库是V3.5,编译环境是Keil uVision4。

  转载请注明完整出处。


1,时钟简介

  上篇介绍了如何创建一个STM32的空模板。搭建好编译环境后,还需要对stm32芯片本身有一定了解,这样才可以配置好芯片跑程序。本篇介绍的是STM32的系统时钟部分,学过数字电路的朋友就知道,时钟对于电路来说就好比是人体的心脏。详细的时钟配置与说明可以参见下面链接中的:《STM32中文参考手册》
  https://download.csdn.net/download/huagengpai1994/10809289
  整个时钟体系可以由下图来表述:

  可以看到图中有蓝色和绿色两种颜色的方块。蓝色方块代表时钟信号源,绿色信号代表信号处理(分频、倍频)与输出。初学只要构建时钟大体的框架就好。
  时钟信号源有四个部分(可忽略PLL)分别是:

  • HSI RC:高速内部RC振荡时钟源,8MHZ。H表示高速,S表示源,I表示内部,RC表示是振荡器。内部时钟源是在芯片(小方块)里面的,外部时钟源是在芯片外部通过PCB布线连接到芯片里。
  • LSI RC:低速内部RC振荡时钟源,大约为40KHZ。
  • HSE Osc: 高速外部晶体振荡时钟源,8MHZ。
  • LSE Osc:低速外部晶体振荡时钟源,32.768KHZ。
      图中俩高速的在上面,俩低速的在下面。
      PLL也被认为是一个时钟源,不过它从原理上来看并不提供时钟源信号,只是对接受的信号倍频后输出。可以从图中看到PLL的时钟路径有两条:HSI RC 2分频、HSE Osc 直接到达、HSE Osc 2分频到达。
      同样的,可以看看下方的RTC时钟,它的时钟源也有三条:HSE Osc 128分频到,LSE Osc 直接到达、LSI RC 直接到达。
      LSI RC还直接供给看门狗独立时钟。
      接着看上面的部分,SYSCLK系统时钟源有三条路径:HSI RC直接到达,PLL到达,HSE Osc 直接到达。CSS如图中的解释,是一个时钟监视,如果HSE失效则自动切换到SYSCLK=HSI。
      SYSCLK系统时钟的频率最高为72MHZ,经过AHB分频后供给AHB1和AHB2。APB1和APB2还要继续分频才能供给外设与计时器,其中APB1是低速的,最高为36MHZ;APB2为高速的,最高为72MHZ。
      中间部分的MCO是将经过芯片的时钟输出出去,输出源如图中所示有四个:SYSCLK、HSI、HSE和PLLCLK2分频。
      总结一下:系统时钟SYSCLK是最核心的部分,图示左上部分无论怎么走都是为了到达系统时钟,然后调配到APB1和APB2为外设输出时钟。
       经过时钟源的选择、分频/倍频,就可以到HCLK(高性能总线AHB用)、FCLK(供给cpu内核的用,常说的cpu主频)、PCLK(高性能外设总线APB)、USBCLK、TIMXCLK、TIM1CLK、RTCCLK等,外设是挂载STM32的总线上的,具体哪个外设挂载哪个总线,看下图:

2,时钟配置

  在编程中,我们要做的也无非是设置门电路以选择时钟源输入、倍频/分频系数和打开/关闭对应外设所在总线的时钟。这些设置是通过寄存器进行设置的,但是直接设置寄存器会有点较复杂,所以可以用SystemInit()库函数直接进行设置。库函数的设置方法如下所示:
const uint32_t SystemFrequency = SYSCLK_FREQ_72MHz;
const uint32_t SystemFrequency_SysClk =SYSCLK_FREQ_72MHz;
const uint32_t SystemFrequency_AHBClk = SYSCLK_FREQ_72MHz;
const uint32_t SystemFrequency_APB1Clk = (SYSCLK_FREQ_72MHz/2);
const uint32_t SystemFrequency_APB2Clk = SYSCLK_FREQ_72MHz;

  这就是在定义了CPU跑72M的时候,各个系统的速度.他们分别是:硬件频率,系统时钟,AHB总线频率,APB1总线频率,APB2总线频率.
  如果需要更加灵活的配置,可以调用这个函数:

void RCC_HSE_Configuration(void) //HSE作为PLL时钟,PLL作为SYSCLK 
{ 
	RCC_DeInit(); /*将外设RCC寄存器重设为缺省值 */
 	RCC_HSEConfig(RCC_HSE_ON);/*设置外部高速晶振(HSE) HSE晶振打开(ON)*/ 
   	if(RCC_WaitForHSEStartUp() == SUCCESS)  /*等待HSE起振,  SUCCESS:HSE晶振稳定且就绪*/  
   	{ 
  		RCC_HCLKConfig(RCC_SYSCLK_Div1);/*设置AHB时钟(HCLK)RCC_SYSCLK_Div1——AHB时钟 = 系统时钟*/  
  		RCC_PCLK2Config(RCC_HCLK_Div1); /*设置高速AHB时钟(PCLK2)RCC_HCLK_Div1——APB2时钟 = HCLK*/     
  		RCC_PCLK1Config(RCC_HCLK_Div2); /*设置低速AHB时钟(PCLK1)RCC_HCLK_Div2——APB1时钟 = HCLK / 2*/
		RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);/*设置PLL时钟源及倍频系数*/    
  		RCC_PLLCmd(ENABLE); 	 /*使能PLL */ 
  		while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET) ;/*检查指定的RCC标志位(PLL准备好标志)设置与否*/ 
  		RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);  /*设置系统时钟(SYSCLK) */  
  		while(RCC_GetSYSCLKSource() != 0x08);     /*0x08:PLL作为系统时钟 */	
  	  }
}

  如果使用void RCC_HSE_Configuration(void),可以将其作为一个.C文件独立编写,然后再主函数直接调用。

猜你喜欢

转载自blog.csdn.net/huagengpai1994/article/details/84568185