一、时钟树
什么是时钟,对单片机有什么作用
时钟是由电路产生的具有周期性的脉冲信号,相当于单片机的心脏,要想使用单片机的外设必须开启相应的时钟,驱动外设的本质是操作寄存器,所以要想操作寄存器必须开启对应外设的时钟。
为什么要有时钟树
STM32时钟系统主要的目的就是给相对独立的外设模块提供时钟,主要也是为了降低整个芯片的功耗,所有外设时钟默认都是关闭状态(disable),当我们使用某个外设就要开启这个外设的时钟(enable),不同外设需要的时钟频率不同,没必要所有外设都用高速时钟造成浪费,而且有些外设也接受不了这么高的频率,这也是为什么STM32有四个时钟源的原因,就是兼容不同速度的外设,STM32的四个时钟源分别为:HSE、LSE、HSI、LSI
- HSE、HSI、PLL属于高速时钟,LSE、LSI属于低速时钟
- 按照来源可以分为外部时钟源和内部时钟源,外部时钟源就是在STM32晶振引脚处接入外部的晶振来获取时钟源,如:HSE、LSE,其余为内部时钟源
HSI时钟
- HSI: High Speed Internal Clock signal,高速的内部时钟,为RC振荡器,频率可以达到8M,可作为系统时钟或者PLL锁相环的输入。
- 来源: 芯片内部,大小为8M,当HSE故障时,系统时钟 会自动切换到HSI,直到HSE启动成功。
- 作用: 可直接作为系统时钟或在2分频后作为PLL输入。HSI RC振荡器能够在不需要任何外部器件的条件下提供系统时钟。它的启动时间比HSE晶体振荡器短。然而,即使在校准之后它的时钟频率精度仍较差
HSE时钟
- HSE: High Speed External Clock signal,即高速的外部时钟,有两个引脚,可以接入外部高速晶振(4M-16M),为了方便计算,一般使用8M。
- 来源: 无源晶振(4-16M),通常使用8M。
- 作用: 可不分频或2分频(频率/2)作为PLL锁相环的输入,还可直接不分频作为系统时钟,128分频作为外设RTC时钟的输入
LSI时钟
- LSI: low Speed Internal Clock signal,低速的内部时钟。
- 来源: 内部芯片,LSI RC担当一个低功耗时钟源的角色,它可以在停机和待机模式下保持运行,LSI时钟频率大约40kHz(在30kHz和60kHz之间)。
- 作用: 为独立看门狗和自动唤醒单元(RTC)提供时钟
- 独立看门狗只能依靠LSI这个内部低速时钟作为它的时钟源
LSE时钟
- LSE: low Speed External Clock signal,低速的外部时钟。
- 来源: 芯片内部,LSE晶体是一个32.768kHz的低速外部晶体或陶瓷谐振器。它为实时时钟或者其他定时功能提供一个低功耗且精确的时钟源。
- 作用: 直接作为RTC是时钟来源
锁相环时钟PLLCLK
- 锁相环时钟: PLLCLK
- 来源: 选择HIS振荡器除2或HSE振荡器为PLL的输入时钟,和选择倍频因子,必须在其被激活前完成。一旦PLL被激活,这些参数就不能被改动。
- 作用: 内部PLL可以用来倍频HSI RC的输出时钟或HSE晶体输出时钟(倍频数2~16倍),而经过倍频变成PLLCLK可以作为系统时钟源
注意:PLL时钟源头使用HIS/2的时候,PLLMUL最大只能 是16,这个时候PLLCLK最大只能是64M,小于ST官方推 荐的最大时钟72M。如果需要在应用中使用USB接口,PLL必须被设置为输出48或72MHZ时钟,用于提供48MHz的USBCLK时钟。
系统时钟SYSCLK
- 系统时钟: SYSCLK,最高为72M(ST官方推荐的)
- 来源: HSI、HSE、PLLCLK。
- 控制: CFGR:SW
- 注意: 通常的配置是
SYSCLK = PLLCLK = 72M
HCLK时钟
- HCLK: AHB高速总线时钟,速度最高为72M。
- 作用: 为AHB总线的外设提供时钟、为Cortex系统定时器提供时钟(SysTick)、为内核提供时(FCLK)。
- 来源: 系统时钟分频得到,一般设置HCLK=SYSCLK=72M
- 控制: CFGR:HPRE
PCLK1时钟
- PCLK1: APB1低速总线时钟,最高为36M。
- 作用: 为APB1总线的外设提供时钟。1或2倍频之后则为APB1总线的定时器2~7提供时钟,最大为72M。
- 来源: HCLK分频得到,一般配置PCLK1=HCLK/2=36M
- 控制: RCC_CFGR 时钟配置寄存器的PPRE1位
PCLK2时钟
- PCLK2: APB2高速总线时钟,最高为72M。
- 作用: 为APB2总线的外设提供时钟。为APB2总线的定时器1和8提供时钟,最大为72M。APB2分频器还有一路输出供ADC分频器使用,分频后送给ADC模块使用。
- 来源: HCLK分频得到,一般配置PCLK1=HCLK=72M
- 控制: RCC_CFGR 时钟配置寄存器的PPRE2位
RTC时钟
- RTC时钟: 为芯片内部的RTC外设提供时钟。
- 来源: HSE_RTC(HSE分频得到)、LSE(外部32.768KHZ的 晶体提供)、LSI(32KHZ)。
- 控制: RCC备份域控制寄存器RCC_BDCR:RTCSEL位控制
- 独立看门狗时钟: IWDGCLK,由LSI提供
时钟安全系统(CSS)
监视高速外部时钟HSE的工作状态。若HSE失效,会自动切换高速内部时钟HSI作为系统时钟的输入,保证系统的正常运行。一旦CSS被激活,并且HSE时钟出现故障,CSS中断就产生,并且NMI也自动产生。NMI将被不断执行,直到CSS中断挂起位被清除。
MCO时钟输出
- MCO: microcontroller clockoutput,微控制器时钟输出引脚,由PA8复用所得。可以把时钟信号输出供外部使用,也可以用示波器检测时钟信号的参数(峰峰值,频率…)
- 来源: PLLCLK/2,HSE、HSI、SYSCLK
- 控制: CRGR:MCO
二、时钟系统配置
- STM32单片机上电,就会执行启动文件(汇编代码编写)中的复位程序。
- 执行复位程序
- 调用SystemInit系统初始化函数完成系统时钟的配置(配置成72MHZ)
- 调用_main函数初始化堆栈指针,然后再调用C库函数main函数,去到C语言的世界 所以跳转到C语言的main函数时,已经完成了系统时钟(SYSCLK)的配置。
三、时钟配置函数
- 时钟初始化配置函数
void SystemInit(void) 会配置如下时钟 SYSCLK(系统时钟) = 72MHz AHB 总线时钟(HCLK=SYSCLK) = 72MHz APB1 总线时钟(PCLK1=SYSCLK/2) = 36MHz APB2 总线时钟(PCLK2=SYSCLK/1) = 72MHz PLL 主时钟 = 72MHz
- 外设时钟使能配置函数
void RCC_AHBPeriphClockCmd(uint32_t RCC_AHBPeriph, FunctionalState NewState) void RCC_APB2PeriphClockCmd(uint32_t RCC_AHBPeriph, FunctionalState NewState) void RCC_APB1PeriphClockCmd(uint32_t RCC_AHBPeriph, FunctionalState NewState)
- 时钟源使能函数
void RCC_HSICmd(FunctionalState NewState); void RCC_LSICmd(FunctionalState NewState); void RCC_PLLCmd(FunctionalState NewState); void RCC_RTCCLKCmd(FunctionalState NewState);
- 时钟源和倍频因子配置函数
RCC_HSEConfig(RCC_HSE_ON); RCC_SYSCLKConfig(RCC_SYSCLKSource_HSE); RCC_HCLKConfig(RCC_SYSCLK_Div1); RCC_PCLK1Config(RCC_HCLK_Div2); RCC_PCLK2Config(RCC_HCLK_Div1); void RCC_PLLConfig(uint32_t RCC_PLLSource, uint32_t RCC_PLLMul); 参数1:来源,参数2:倍频系数
- 外设时钟复位函数
void RCC_APB1PeriphResetCmd(uint32_t RCC_APB1Periph, FunctionalState NewState) void RCC_APB2PeriphResetCmd(uint32_t RCC_APB2Periph, FunctionalState NewState)
- 对于STM32F10系列高容量的芯片是没有AHB总线上的外设的,对于复位这些就没有AHB
四、自定义系统时钟
参数1:HSE的分频系数,参数2:PLL的倍频系数(2-16)
void RCC_HSE_Config(u32 div,u32 pllm) //自定义系统时间(可以修改时钟)
{
RCC_DeInit(); //将外设RCC寄存器重设为缺省值,即默认状态的值
RCC_HSEConfig(RCC_HSE_ON);//设置外部高速晶振(HSE)
if(RCC_WaitForHSEStartUp()==SUCCESS) //等待HSE起振
{
// 下面3个是要设置分频系数
RCC_HCLKConfig(RCC_SYSCLK_Div1);//设置AHB时钟(HCLK)
RCC_PCLK1Config(RCC_HCLK_Div2);//设置低速AHB时钟(PCLK1)
RCC_PCLK2Config(RCC_HCLK_Div1);//设置高速AHB时钟(PCLK2)
// 配置时钟来源和倍频系数,由形参传递进来
RCC_PLLConfig(div,pllm);//设置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:PLL作为系统时钟
}
}
五、代码实现
main.c
LED.c
LED.h
文档信息
- 本文作者:magicianplus
- 本文链接:https://magicianplus.github.io/2024/11/24/%E7%AC%AC10%E7%AB%A0-STM32%E6%97%B6%E9%92%9F%E7%B3%BB%E7%BB%9F/
- 版权声明:自由转载-非商用-非衍生-保持署名(创意共享3.0许可证)