欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

STM32笔记 (五) RCC时钟系统

程序员文章站 2022-04-02 07:54:40
...

简介

由于STM32的性能强大,内部组成复杂,而且时钟频率普遍比51单片机高,不能简单的用一个51单片机的时钟系统来调配,对于F1系列时钟频率高达72MHz,如果把STM32的每一个外设的时钟都打开,那么功耗是不可想象的,同时对于一个电路,时钟频率越快,抗干扰能力就越弱,因此STM32采用了多时钟源的方式来解决这些问题,并且对于每一个片上外设,都需要单独设置时钟的使能位。

时钟源

  1. HSE时钟–High Speed External Clock Signal (高速外部时钟)
    精度高,位于芯片外部,通过OSC_IN 和OSC_OUT 引脚连接外部晶振
    常用的是无源晶振(4~16MHZ)通常使用8MHZ(无源) ,一般倍频为72MHZ

晶振分类:
1.无源晶振是有2个引脚的无极性元件,需要借助于时钟电路才能产生振荡信号,自身无法振荡起来
2.有源晶振有4只引脚,是一个完整的振荡器,其中除了石英晶体外,还有晶体管和阻容元件主要看 你应用到的电路,如果有时钟电路,就用无源,否则就用有源。

  1. HSI时钟–High Speed Internal Clock Signal(高速内部时钟)
    位于芯片内部,当外部时钟出现故障时,会切换使用HSI时钟,直到HSE启动成功
    大小为8MHZ 一般会被分频成4MHZ
  2. LSE时钟–Low Speed External Clock Signal(低速外部时钟)
    位于芯片外部,通过OSC32_IN和OSC32_OUT连接频率为32.768MHz的石英晶体
  3. LSI时钟–Low Speed Internal Clock Signal(低速内部时钟)
    位于芯片内部,是一个RC震荡器,频率为40KHz
  4. PLLCLK–锁相倍频时钟源
    PLLCLK本身的不是一个独立的内部或者外部时钟源,其来源可以是HSE或者HSI

相关寄存器

typedef struct
{
  __IO uint32_t CR; //时钟控制寄存器
  __IO uint32_t CFGR; //时钟配置寄存器
  __IO uint32_t CIR; //时钟中断寄存器
  __IO uint32_t APB2RSTR; //APB2 外设复位寄存器 
  __IO uint32_t APB1RSTR; //APB1 外设复位寄存器
  __IO uint32_t AHBENR; //AHB外设时钟使能寄存器 
  __IO uint32_t APB2ENR; //APB2 外设时钟使能寄存器 常用
  __IO uint32_t APB1ENR; //APB2 外设时钟使能寄存器 常用
  __IO uint32_t BDCR; //备份域控制寄存器
  __IO uint32_t CSR; //控制/状态寄存器 
  }RCC_TypeDef;

时钟树

稍加注释,原版可在参考手册中找到
STM32笔记 (五) RCC时钟系统
几个名词这里解释一下:
分频:指的的将时钟频率除以一个常数,分频因子就是这个常数,例如,16MHz经过2分频后就是8MHz
倍频:将时钟频率乘以一个常数,倍频因子就是这个常数,例如,8MHz经过9倍倍频后就是72MHz


APB1和APB2总线配置流程图示例
STM32笔记 (五) RCC时钟系统


RTC(实时时钟)时钟源

实时时钟是一个独立的定时器。 RTC模块拥有一组连续计数的计数器,在相应软件配置下,可
提供时钟日历的功能。修改计数器的值可以重新设置系统当前的时间和日期。

STM32笔记 (五) RCC时钟系统
RTC 时钟可由 HSE/128 分频得到,也可由低速外部时钟信号 LSE 提供,频率为32.768KHZ,也可由低速内部时钟信号 HSI 提供,具体选用哪个时钟由备份域控制寄存器BDCR 的位 9-8: RTCSEL[1:0]配置。独立看门狗的时钟由 LSI 提供,且只能是由 LSI 提供(LSI 是低速的内部时钟信号,频率为 30~60KHZ 直接不等,一般取 40KHZ)。

MCO 时钟输出

  • MCO 是 Microcontroller Clock Output 的缩写,STM32允许输出时钟信号到外部MCO引脚,可以对外提供时钟,相当于一个有源晶振
  • 时钟来源有: PLLCLK/2HSIHSESYSCLK
  • RCC->CFGR寄存器配置
    STM32笔记 (五) RCC时钟系统

配置HSE为系统时钟

编程要点:

  1. 开启 HSE , 等待 HSE稳定
  2. 设置 AHB、 APB2、 APB1 的预分频因子
  3. 设置 PLL 的时钟来源,和 PLL 的倍频因子
  4. 开启 PLL,等待 PLL 稳定
  5. 把 PLLCK 切换为系统时钟 SYSCLK
  6. 读取时钟切换状态位,确保 PLLCLK 被选为系统时钟
void HSE_SetSysClk( uint32_t RCC_PLLMul_x ) //x为倍频因子,如RCC_PLLMul_9
{
	ErrorStatus ErrorStatus;
	
	//把RCC复位成刚上电的状态
	RCC_DeInit();

	//使能HSE
	RCC_HSEConfig(RCC_HSE_ON);
	
	//等待HSE设置成功 返回success和error
	ErrorStatus	= RCC_WaitForHSEStartUp();
	
	if( ErrorStatus == SUCCESS ) //如果启动成功
	{
		//使能预取址
		FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
		
		FLASH_SetLatency(FLASH_Latency_2);
		
		//AHB总线分频为1
		RCC_HCLKConfig(RCC_SYSCLK_Div1);
		//APB1总线分频为
		RCC_PCLK1Config(RCC_HCLK_Div2);
		//APB2总线分频为
		RCC_PCLK2Config(RCC_HCLK_Div1);
		
		//配置PLL锁相环   
		//配置PLLCLK = HSB * RCC_PLLMul_x (倍频因子)
		RCC_PLLConfig(RCC_PLLSource_HSE_Div1,RCC_PLLMul_x);//8*x = xxxMHz
		
		//使能PLL
		RCC_PLLCmd(ENABLE);
		//等待PLL稳定
		while( RCC_GetFlagStatus( RCC_FLAG_PLLRDY ) == RESET );
		
		//选择系统时钟为PLLCLK
		RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
		//检查系统时钟来源是否正确
		while( RCC_GetSYSCLKSource() != 0x08 );
		
		
	}
	else //启动失败
	{
		/* 可以在这里添加错误时运行的代码 */
	}
	
}

相关标签: STM32笔记