STM32时钟系统简介

目录

STM32时钟系统

时钟系统框图

时钟系统总结

PLLCLK,SYSCLK,HCKL,PCLK1,PCLK2 之间的关系

五大时钟源

简要概述系统时钟源

APB1&ABP2总线对应的设备

与时钟相关的寄存器

STM32官方库函数讲解

时钟初始化SystemInit()函数

系统文件中跨文件全局变量的宏定义声明


STM32时钟系统

时钟系统框图

 

时钟系统总结

PLLCLK,SYSCLK,HCKL,PCLK1,PCLK2 之间的关系

1、HSI:高速内部时钟信号 stm32单片机内带的时钟 (8M频率)精度较差

2、HSE:高速外部时钟信号精度高来源(1)HSE外部晶体/陶瓷谐振器(晶振) (2)HSE用户外部时钟

3、LSE:低速外部晶体 32.768kHz 主要提供一个精确的时钟源 一般作为RTC时钟使用

五大时钟源

LSE:低速外部晶体 32.768kHz 主要提供一个精确的时钟源 一般作为RTC时钟使用

在STM32中,有五个时钟源,为HSI、HSE、LSI、LSE、PLL:

①、HSI是高速内部时钟,RC振荡器,频率为8MHz。

②、HSE是高速外部时钟,可接石英/陶瓷谐振器,或者接外部时钟源,频率范围为4MHz~16MHz。

③、LSI是低速内部时钟,RC振荡器,频率为40kHz。

④、LSE是低速外部时钟,接频率为32.768kHz的石英晶体。

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

简要概述系统时钟源

 

注:USB模块虽然需要一个单独的48MHz时钟信号,但它应该不是供USB模块工作的时钟,而只是提供给串行接口引擎(SIE)使用的时钟。USB模块工作的时钟应该是由APB1提供的,这个图中输出端口不太全,该图旨在说明核心系统时钟源的功能。

APB1&ABP2总线对应的设备

连接在APB1(低速外设)上的设备有:电源接口、备份接口、CAN、USB、I2C1、I2C2、UART2、UART3、SPI2、窗口看门狗、Timer2、Timer3、Timer4;

连接在APB2(高速外设)上的设备有:UART1、SPI1、Timer1、ADC1、ADC2、所有普通IO口(PA~PE)、第二功能IO口。

与时钟相关的寄存器

我们要知道无论是STM32官方提供的库函数还是其提供的寄存器操作方法,本质上来说都是对相应的寄存器进行操作。

RCC 寄存器结构,RCC_TypeDeff,在文件“stm32f10x_map.h”中定义如下:

typedef struct

{

vu32 CR;                  //HSI,HSE,CSS,PLL等的使能

vu32 CFGR;              //PLL等的时钟源选择以及分频系数设定

vu32 CIR;                // 清除/使能 时钟就绪中断

vu32 APB2RSTR;      //APB2线上外设复位寄存器

vu32 APB1RSTR;      //APB1线上外设复位寄存器

vu32 AHBENR;         //DMA,SDIO等时钟使能

vu32 APB2ENR;       //APB2线上外设时钟使能

vu32 APB1ENR;      //APB1线上外设时钟使能

vu32 BDCR;           //备份域控制寄存器

vu32 CSR;          

} RCC_TypeDef;

这里RCC是Reset and clock control的缩写,意为“复位与时钟控制”

STM32官方库函数讲解

时钟初始化SystemInit()函数

我们知道在操作STM32开发板之前,必须先初始化全部的时钟,是他们均恢复到默认状态,然后我们再在函数文件中使能相应的时钟。那问题来了,我们一般编写函数文件时没用过SystemInit()函数呀?SystemInit()函数是怎么调用的?

SystemInit()函数在哪里定义的?

 

SystemInit()函数在那里被调用的?

由于SystemInit()函数调用是STM32的核心代码,因此放到启动文件中,如果要查找可以在CORE->startup_stm32f10x_xx.s中找到。

 

更加个性化的系统初始化函数调用

; Reset handler  
Reset_Handler   PROC  
                EXPORT  Reset_Handler             [WEAK]  
                IMPORT  __main  
                IMPORT  SystemInit // 如果你编写了自己的时钟初始化函数可以将SystemInit换为你自己的初始化函数  
                LDR     R0, =SystemInit  
                BLX     R0                 
                LDR     R0, =__main  
                BX      R0  
                ENDP  

 

 

SystemInit()函数如何工作?

// 系统初始化函数SystemInit()  
void SystemInit (void)  
{  
  /* 将RCC时钟配置重置为默认重置状态(用于调试) */  
  /* 设置 HSION 位为1 , 即默认状态下系统时钟源为HSI*/  
  RCC->CR |= (uint32_t)0x00000001;  
    
  /* 设置 HSEON, CSSON and PLLON 位为0 */  
  RCC->CR &= (uint32_t)0xFEF6FFFF;  
  
  /* 设置 HSEBYP 位为0 */  
  RCC->CR &= (uint32_t)0xFFFBFFFF;  
  
  /* 设置 PLLSRC, PLLXTPRE, PLLMUL and USBPRE/OTGFSPRE 位为0 */  
  RCC->CFGR &= (uint32_t)0xFF80FFFF;  
  
  /* 配置系统时钟频率,HCLK, PCLK2和PCLK1分频器 */  
  /* 配置Flash延迟周期并启用预取缓冲区 */  
  SetSysClock(); // 用于配置系统时钟频率,HCLK, PCLK2和PCLK1预压器  
  
#ifdef VECT_TAB_SRAM  
  SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM. */  
#else  
  SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH. */  
#endif   
}  
// 系统时钟速度配置函数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  
   
 /* 如果以上定义都没有启用,则HSI将用作系统时钟源(使用默认值) */   
}  

 

此外,我们还可以自定义初始速度:

 

只要我们把注释掉的预定义命令恢复,就可以配置不同速度。

可以读出系统时钟速度的变量SystemCoreClock:

/******************************************************************************* 
*  Clock Definitions 
*******************************************************************************/  
#ifdef SYSCLK_FREQ_HSE  
  uint32_t SystemCoreClock         = SYSCLK_FREQ_HSE;        /*!< System Clock Frequency (Core Clock) */  
#elif defined SYSCLK_FREQ_24MHz  
  uint32_t SystemCoreClock         = SYSCLK_FREQ_24MHz;        /*!< System Clock Frequency (Core Clock) */  
#elif defined SYSCLK_FREQ_36MHz  
  uint32_t SystemCoreClock         = SYSCLK_FREQ_36MHz;        /*!< System Clock Frequency (Core Clock) */  
#elif defined SYSCLK_FREQ_48MHz  
  uint32_t SystemCoreClock         = SYSCLK_FREQ_48MHz;        /*!< System Clock Frequency (Core Clock) */  
#elif defined SYSCLK_FREQ_56MHz  
  uint32_t SystemCoreClock         = SYSCLK_FREQ_56MHz;        /*!< System Clock Frequency (Core Clock) */  
#elif defined SYSCLK_FREQ_72MHz  
  uint32_t SystemCoreClock         = SYSCLK_FREQ_72MHz;        /*!< System Clock Frequency (Core Clock) */  
#else /*!< HSI Selected as System Clock source */  
  uint32_t SystemCoreClock         = HSI_VALUE;        /*!< System Clock Frequency (Core Clock) */  
#endif  

 

系统文件中跨文件全局变量的宏定义声明

 

图中“STM32F10X_HD,USE_STDPERIPH_DRIVER “为所有文件均能识别的宏定义标志,其中我们很常见的是” STM32F10X_HD “,它代表的是大容量芯片。

 

  • 2
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
STM32系统时钟是指控制STM32芯片内部各个模块和外设运行的时钟信号。STM32时钟系统相对复杂,对于初学者来说可能会感到困惑。时钟系统的重要性不言而喻,它类似于人体的心脏脉搏,是整个系统的基础。\[1\] 为了更好地理解STM32时钟系统,初学者可以参考开发板的源码进行设置,但这种方法可能会导致在遇到问题或需要修改代码时感到困惑。要深入理解STM32时钟系统,以便进行底层驱动设计,需要对其有更深入的了解。\[2\] 在配置STM32时钟系统时,可以根据实际情况进行自定义设置。一般情况下,可以以大容量芯片72MHz的系统时钟为例进行讲解,原理都是一样的。\[3\] 总之,STM32系统时钟是控制芯片内部各个模块和外设运行的关键信号,对于深入理解和设计底层驱动非常重要。 #### 引用[.reference_title] - *1* *3* [STM32-时钟系统详解](https://blog.csdn.net/qq_44016222/article/details/123223733)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [【STM32】初学者必读STM32时钟系统详解](https://blog.csdn.net/m0_54916619/article/details/130182697)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

肥肥胖胖是太阳

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值