STM32103_SYSCLOCK_MYNOTE

以STM32F103C8T6为例,参考《技术手册》,《数据手册》,《标准库函数手册》,个人学习笔记,供参考和指正。

·STM32103C8T6共5个时钟源,HSE,HSI,PLL,LSE,LSI,前三者为系统时钟源,LSE和LSI用于驱动RTC,LSI用于喂养看门狗

·AHB域和APB2域的最大为72MHZ;APB1域最大允许频率为36MHZ;

·如果HSE晶体振荡器失效,HSI时钟会被作为备用时钟源;

·HSI通常不会作为系统时钟,因为即使在校准之后它的时钟频率精度仍较差

·附录,库函数表

ac2588b38fbb6809dd37baf94a22e7e6.png

4e061168ae925c6114b00f533df003f2.png

1)为什么一句APB2外设时钟使能,一个GPIO初始化,就可以运行,在这之前,你并没有配置时钟?

2)如果HSE晶体振荡器失效,HSI时钟会被作为备用时钟源?

3)如果我想要配置HSI_PLL系统时钟频率为64MHZ该怎么操作?

4)如果我想要配置HSE_PLL系统时钟频率为48MHZ该怎么操作?


1)为什么一句APB2外设时钟使能,一个GPIO初始化,就可以运行,在这之前,你并没有配置时钟?

因为在启动文件中已经默认配置时钟为72MHZ;每次设备复位后,先开启HSI(因为它的启动时间较短为什么要配置外部时钟,因为HSI不太稳定通常易受到干扰),然后再由HSE经PLL倍频为72MHZ。在system_stm32f103x.c文件中查到

After each device reset the HSI (8 MHz) is used as system clock source.
Then SystemInit() function is called, in "startup_stm32f10x_xx.s" file, 
to configure the system clock before to branch to main program.

在启动文件的SystemInit函数中首先开启了HSI时钟

RCC->CR |= (uint32_t)0x00000001;/* Set HSION bit */

在 SystemInit函数中的SetSysClock函数,继续初始化时钟

static void SetSysClock(void)
{
#ifdef SYSCLK_FREQ_HSE   
  SetSysClockToHSE();
#elif defined SYSCLK_FREQ_24MHz
  SetSysClockTo24();
#elif defined SYSCLK_FREQ_36MHz
  SetSysClockTo36();
#elif defined SYSCLK_FREQ_48MHz
  SetSysClockTo48();
#elif defined SYSCLK_FREQ_56MHz
  SetSysClockTo56();  
#elif defined SYSCLK_FREQ_72MHz
  SetSysClockTo72();
#endif 
 /* If none of the define above is enabled, the HSI is used as System clock
    source (default after reset重置后的默认值),如果以上定义都没有启用, HSI将用作系统时钟,也就是8MHZ的系统时钟*/ 
}

在system_stm32f103x.c文件中。如果宏定义STM32F10X_LD_VL或STM32F10X_MD_VL或 STM32F10X_HD_VL,系统频率被选为24MHZ,如果没有,将宏定义SYSCLK_FREQ_72MHz,系统时钟会被选择为72MHZ,然后会在上面执行  SetSysClockTo72();

#if defined (STM32F10X_LD_VL) || (defined STM32F10X_MD_VL) || (defined STM32F10X_HD_VL)
/* #define SYSCLK_FREQ_HSE    HSE_VALUE */
 #define SYSCLK_FREQ_24MHz  24000000
#else
/* #define SYSCLK_FREQ_HSE    HSE_VALUE */
/* #define SYSCLK_FREQ_24MHz  24000000 */ 
/* #define SYSCLK_FREQ_36MHz  36000000 */
/* #define SYSCLK_FREQ_48MHz  48000000 */
/* #define SYSCLK_FREQ_56MHz  56000000 */
#define SYSCLK_FREQ_72MHz  72000000
#endif

默认选项为 SYSCLK_FREQ_72MHz,执行SetSysClockTo72()

{HSE使能—等待HSE稳定,如果超时则退出—配置FLASH—配置HCLK为系统主频(1分频), PCLK2为系统主频(1分频) ,PCLK1为36MHZ(2分频)—锁相环配置 PLLCLK = HSE * 9 = 72 MHz—使能锁相环—等待锁相环稳定—选择锁相环时钟为系统时钟源—等待锁相环被用于系统时钟源},在调试窗口中查看频率,SYS和APB2域和HCLK为72MHZ,APB1域为36MHZ

38a9c08f12a44d62da6921c385305f89.png

 


2)如果HSE晶体振荡器失效,HSI时钟会被作为备用时钟源?

If HSE fails to start-up, the application will have wrong clock configuration. User can add here some code to deal with this error

在system_stm32f103x.c文件中可以看到上图中的注释,在HSE启用失败后,PLL无法锁定成功。SetSysClockTo72函数中让我们自己添加处理办法,如果没有添加,系统时钟将仍然是SystemInit中配置的HSI的8MHZ。


3)如果我想要配置系统时钟源为HSI_PLL,频率为64MHZ该怎么操作?

/*********************************************************
* @data : 2024/4/15-4/17
* @MCU: STM32F103C8T6
*********************************************************/
#include "stm32f10x.h"              
int main()
{ 	/*初始化RCC*/
	RCC_DeInit();
	/*使能HSI,此步骤可以省略,在RCC_DeInit()中已经打开了HSI*/
	RCC_HSICmd(ENABLE);
	/*配置PLL时钟源为HSI的2分频的16倍频*/
	RCC_PLLConfig(RCC_PLLSource_HSI_Div2,RCC_PLLMul_16);
	/*使能PLL*/
	RCC_PLLCmd(ENABLE);
	/*等待PLL稳定,就位后相应标志位被置SET*/
    /*只有当目标时钟源准备就绪了(经过启动稳定阶段的延迟或PLL稳定),从一个时钟源到另一个时 钟源的                        
    切换才会发生。在被选择时钟源没有就绪时,系统时钟的切换不会发生。直至目标时钟 源就绪,才发生切 
    换。*/
	while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY)==RESET);	
	/*SW选择系统时钟源为PLL*/
	RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
	/*AHB分频*/
	RCC_HCLKConfig(RCC_SYSCLK_Div1);
	/*APB12分频*/
  RCC_PCLK1Config(RCC_HCLK_Div2);
	/*APB21分频*/
	RCC_PCLK2Config(RCC_HCLK_Div1);
	/*检查目标时钟源是否设置成功*/        
  while (RCC_GetSYSCLKSource() != 0x08);
	/*返回时钟频率,便于在调试窗口查看频率值*/		
	while(1);
}

7010e4133a57f76ce9eea5ebf78bbf2a.png在调试窗口中查看,各频率的值均符合预期,系统频率为64MHZ,HCLK分频后的频率为64MHZ,APB1域的频率为32MHZ,APB2域的频率为64MHZ;

使用RCC_DeInit()后的几个值,在参考手册RCC_CFGR寄存器中描述到PCLK,HCLK1,HCLK2的复位值,使用该函数复位后,HSI直接作为系统时钟,PCLK,HCLK1,HCLK2均不分频

99827cd5d10e23e00857a5c778a841d7.png

ae5c744135ea375a6eb529f177c09ed5.png

4afaab5f55bb712511fd97a34c2a0e97.png

在调试窗口中查看使用RCC_DeInit()后各频率的值,前4者的频率均为8MHZ; 

757946ddd2ae63097aabadf6de563848.png


4)如果我想要配置HSE_PLL系统时钟频率为48MHZ该怎么操作?

4.1.system_stm32f103x.c文件中修改。如果你的文件上带了一把钥匙,找到文件所在地,右键单击点击属性取消勾选只读;

eac1df504cd386074376ac69dab4822a.png

83f2860168c3308406e32191cbd1d6f7.png

修改注释即可,如要配置48MHZ修改为如图 

ba52e59276aed7aec4198fca7ca0c612.png

 在调试窗口中查看,系统频率和APB2域和HCLK为48MHZ,APB1域为24MHZ;d335300c4bb1d0ed9249a5993aa4c2ef.png


4.2.在主函数中单独配置

/*********************************************************
* @data : 2024/4/15-4/17
* @MCU: STM32F103C8T6
*********************************************************/
#include "stm32f10x.h"              
int main()
{	
	RCC_DeInit();/*将外设 RCC 寄存器重设为缺省值*/
	RCC_HSEConfig(RCC_HSE_ON); /*设置外部高速晶振*/
	while(RCC_WaitForHSEStartUp() != SUCCESS);/*等待 HSE 起振*/
	while(RCC_GetFlagStatus(RCC_FLAG_HSERDY) != SET);/*HSE 晶振就绪*/
 	RCC_HCLKConfig(RCC_SYSCLK_Div1);/*设置 AHB 时钟*/
  RCC_PCLK1Config(RCC_HCLK_Div2);/*设置低速 AHB 时钟*/	
  RCC_PCLK2Config(RCC_HCLK_Div1);/*设置高速 AHB 时钟*/
	RCC_PLLConfig(RCC_PLLSource_HSE_Div1,RCC_PLLMul_6);/*设置 PLL 时钟源及倍频系数*/
	RCC_PLLCmd(ENABLE);/*使能PLL*/	
	while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) != SET);/*PLL 就绪*/
	RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);/*设置系统时钟*/
	while(RCC_GetSYSCLKSource() != 0X08);/*检查PLL是否作为系统时钟源*/
	//RCC_ClocksTypeDef  RCC_Clocksstructure; 	
    //RCC_GetClocksFreq(&RCC_Clocksstructure);		
	while(1);
}

 调试窗口中,系统频率和APB2域和HCLK为48MHZ,APB1域为24MHZ;

0c0523731e7e47f173cdedcbeaf471d9.png



829c2ef0be14281976481a77b93de8dc.png

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值