4、STM32时钟系统

时钟

时钟是单片机运行的基础,时钟源像心脏,时钟频率像心跳。有了时钟,才能够运行执行指令,才能够做其他的处理 。(IO口,串口,ADC等)

为什么 STM32 要有多个时钟源呢?

为了降低芯片耗能呗。时钟越快功耗越快,且抗电磁干扰能力越弱。任何一个时钟源都能够被独立地启动或关闭。(所有的外设时钟初始状态都是未使能的)

STM32外设很多  但用到的不多。只要用外设就得要时钟,加上有的外设也不需要系统时钟那么高的频率,so,多点时钟源哪个好用用哪个,能适应不同场所。

STM32时钟系统

STM32 有4个独立时钟源:HSI、HSE、LSI、LSE。
1、HSI是高速内部时钟,RC振荡器,频率为8MHz,精度不高。
2、HSE是高速外部时钟,可接石英/陶瓷谐振器,或者接外部时钟源,频率范围为4MHz~16MHz。
3、LSI是低速内部时钟,RC振荡器,频率为40kHz,提供低功耗时钟。(作为IWDGCLK(独立看门狗)时钟源和RTC时钟源而独立使用) 
4、LSE是低速外部时钟,接频率为32.768kHz的石英晶体。

PLL为锁相环倍频输出,其时钟输入源可选择为HSI/2、HSE或者HSE/2。倍频可选择为2~16倍,但是其输出频率最大不得超过72MHz。

有的说法将PLL当作第5个时钟源,但实际上PLL并非自己产生的时钟源,而是通过其他三个时钟源倍频得到的。


系统时钟

处理器运行时间的基准(每一条机器指令一个时钟周期)。

HSI、HSE、PLL这三个时钟源经过分频和倍频后,可被用来作为系统时钟(SYSCLK)。(最大约72M)

系统默认的时钟为72Mhz,两个来源方式:

1、外部晶振(HSE)提供的8MHz,通过PLLXTPRE分频器后,进入PLLSRC选择开关,进而通过PLLMUL锁相环进行倍频(x9)后,为系统提供72MHz的系统时钟。之后是AHB预分频器对时钟信号进行分频,然后为低速外设提供时钟。

2、或者,内部RC振荡器(HSI) 为8MHz  /2 为4MHz 进入PLLSRC选择开关,通过PLLMUL锁相环进行倍频(x18)后 为72MHz。

时钟初始化的值

SystemInit() 函数中设置的系统时钟大小:

SYSCLK(系统时钟) =72MHz

AHB 总线时钟(使用 SYSCLK) =72MHz

APB1 总线时钟(PCLK1) =36MHz

APB2 总线时钟(PCLK2) =72MHz

PLL 时钟 =72MHz

所有人都绕不开的时钟树:

左边部分是设置系统时钟的时钟源,   

系统时钟SYSCLK的右边,是系统时钟通过AHB预分频器,给相对应的外设设置相对应的时钟频率

从左到右:各个时钟源--->系统时钟来源的设置--->各个外设时钟的设置

系统时钟通过AHB分频器给外设提供时钟

 从左到右:系统时钟--->AHB分频器--->各个外设分频倍频器 --->外设时钟的设置

右边部分为:系统时钟SYSCLK通过AHB分频器分频后送给各模块使用,AHB分频器可选择1、2、4、8、16、64、128、256、512分频。其中AHB分频器输出的时钟送给5大模块使用: 

 ①内核总线:送给AHB总线、内核、内存和DMA使用的HCLK时钟。 

 ②Tick定时器:通过8分频后送给Cortex的系统定时器时钟。 

 ③I2S总线:直接送给Cortex的空闲运行时钟FCLK。 

 ④APB1外设:送给APB1分频器。APB1分频器可选择1、2、4、8、16分频,其输出一路供APB1外设使用(PCLK1,最大频率36MHz),另一路送给通用定时器使用。该倍频器可选择1或者2倍频,时钟输出供定时器2-7使用。 

 ⑤APB2外设:送给APB2分频器。APB2分频器可选择1、2、4、8、16分频,其输出一路供APB2外设使用(PCLK2,最大频率72MHz),另一路送给高级定时器。该倍频器可选择1或者2倍频,时钟输出供定时器1和定时器8使用。

另外,APB2分频器还有一路输出供ADC分频器使用,分频后送给ADC模块使用。ADC分频器可选择为2、4、6、8分频。 

注意:定时器时钟频率分配由硬件按以下2种情况自动设置:

1. 如果相应的APB预分频系数是1,定时器的时钟频率与所在APB总线频率一致:

        (TIMxCLK) =PCLKx。

2. 否则,定时器的时钟频率被设为与其相连的APB总线频率的2倍:

        TIMxCLK = 2xPCLKx。


RCC初始化:

使用HSE时钟时(正常用的也就是外部时钟HSE)

程序设置时钟参数流程
1、将RCC寄存器重新设置为默认值   RCC_DeInit;
2、打开外部高速时钟晶振HSE       RCC_HSEConfig(RCC_HSE_ON);
3、等待外部高速时钟晶振工作      HSEStartUpStatus = RCC_WaitForHSEStartUp();
4、设置AHB时钟         RCC_HCLKConfig;
5、设置高速AHB时钟     RCC_PCLK2Config;
6、设置低速速AHB时钟   RCC_PCLK1Config;
7、设置PLL              RCC_PLLConfig;
8、打开PLL              RCC_PLLCmd(ENABLE);
9、等待PLL工作          while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)
10、设置系统时钟        RCC_SYSCLKConfig;
11、判断是否PLL是系统时钟     while(RCC_GetSYSCLKSource() != 0x08)
12、打开要使用的外设时钟      RCC_APB2PeriphClockCmd()/RCC_APB1PeriphClockCmd()

实例

1、分析使用的内外设(假设需用到GPIOA和USART2)

2、根据时钟树一次编程打开

程序如下

void RCC_Configuration(void)
{
	//----------使用外部RC晶振-----------
	RCC_DeInit();			//初始化为缺省值
	RCC_HSEConfig(RCC_HSE_ON);	//使能外部的高速时钟 
	while(RCC_GetFlagStatus(RCC_FLAG_HSERDY) == RESET);	//等待外部高速时钟使能就绪

	RCC_PLLConfig(RCC_PLLSource_HSE_Div1,RCC_PLLMul_9);	//PLLCLK = 8MHZ * 9 =72MHZ
	RCC_PLLCmd(ENABLE);			//Enable PLLCLK
	while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);	//Wait till PLLCLK is ready

    RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);	//Select PLL as system clock
	while(RCC_GetSYSCLKSource()!=0x08);		//等至PLL被用作系统时钟源
		
	RCC_HCLKConfig(RCC_SYSCLK_Div1);		//AHB使用系统时钟,HCLK = SYSCLK
	RCC_PCLK2Config(RCC_HCLK_Div1);			//APB2为HCLK/1,PCLK2 =  HCLK
	RCC_PCLK1Config(RCC_HCLK_Div2);			//PCLK1 = HCLK/2

	/*******配置RCC时钟,打开相应外设时钟******/
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);	//使能APB2外设的GPIOA的时钟
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2,ENABLE);	//使能APB1外设的USART2的时钟//用到哪些开哪些
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值