系列文章目录
STM32F4的LED点灯
文章目录
- 系列文章目录
- STM32F4的LED点灯
- 前言
- 1 时钟系统的作用
- 2 STM32中时钟源的分类
- 3 主锁相环PLL的介绍及配置
- 3.1 主锁相环简介
- 3.2 HSE、HSI和主PLL的使能
- 4 系统时钟时钟源的选择
- 5 系统时钟输出时钟源
- 初始化时钟
前言
对STM32单片机时钟系统的简单介绍
目标:了解32的时钟系统,并能够按需进行配置。
1 时钟系统的作用
单片机中包含大量的电路模块,而模块中又有着许多电路,这些电路就像早高峰十字路口的车,没有交警(时钟)协调指挥,就容易撞车。时钟系统为单片机中的电路提供协调节拍,使电路能够有序工作,以达成控制目的。STM32的系统时钟用于向各模块提供时钟信号来源,不同模块所需信号频率不一致,时钟来源也不同。
2 STM32中时钟源的分类
STM32时钟树(部分)如图13所示。
如图13所示,STM32的时钟源有四种。
- 内置低速时钟LSI(Low Speed Inside):频率为32Khz,用来供独立看门狗和自动唤醒单元使用。
- 外置低速时钟LSE(Low Speed External):需要外接频率为32.768kHz 的石英晶体(外部电路)主要作为 RTC 的时钟源。
- 高速内部时钟HSI(High Speed Inside):频率为16MHz,可以用作系统时钟SYSCLK,也可以作为PLL的输入。成本低,启动速度快,但精度差。
- 外置高速时钟HSE(High Speed External):需要外接频率为4-26MHz 的石英晶体(外部电路),一般接8MHz,可作为 RTC 的时钟源、系统时钟SYSCLK,也可以作为PLL的输入。
3 主锁相环PLL的介绍及配置
3.1 主锁相环简介
锁相环用于将频率抬高。
STM32的时钟树中有两个锁相环,一个是主PLL,一个是专用PLL。主 PLL有两个不同的输出信号,一个经P分频后变为PLLCLK,一般被用作系统时钟Sysclk的来源,频率最高为168Mhz;另一个经Q分频后变为48Mhz的PLL48CK。主PLL的结构框图如下图所示。
如图所示,主PLL的输入信号可由HSI和HSE提供,xN表示N倍频,/M、/P和/Q分别代表M、P和Q分频。如果外部晶振的频率已经确定了,那么可以通过设置系数M、N和P来配置系统时钟频率。
主PLL中的M、N、P、Q四个参数在时钟系统控制寄存器系统中的寄存器RCC_PLLCFGR中配置。
PLLCFGR的位定义如下表所示。
由表可见,RCC_PLLCFGR的bit0–bit5用于保存M值,bit6–bit14用于保存N值,bit16–bit17用于保存P值,bit24–bit25用于保存Q值。
对M、N、P和Q的值进行设置:
RCC_PLLCFGR = pllm|(plln<<6)|(((pllp>>1)-1)<<16)|(pllq<<24)|(1<<22);
3.2 HSE、HSI和主PLL的使能
HSE、HSI和PLL等时钟电路都需要使能才能工作,HSE、HSI、PLL的启动控制由寄存器RCC_CR的相关位控制。
RCC_CR寄存器的定义如下表所示。
- bit[1:0]位为内部高速时钟HSI控制位
- bit[17:16]位为外部高速时钟HSE控制位
- bit[25:24]位为PLL控制位
- bit[27:26]位为PLLI2S控制位
四者控制原理大致相同,以bit[1:0]为例:
bit0位为STM32内部高速时钟HSI使能位,配置为1时使能HSI,为0时HSI关闭。
bit1位用于判断HSI是否已经就绪,为1说明已经就绪。
4 系统时钟时钟源的选择
系统时钟可由主PLL、HSI或者HSE的提供,具体到底由这三者中的哪个提供,需要在RCC_CFGR寄存器中配置。
RCC_CFGR寄存器的定义如下表所示:
SW表示三路选择开关(见图13),bit[1:0]即用于选择系统时钟源,当将其设置为10时,即选择主PLL的输出作为系统时钟源。由于时钟信号从开始切换到稳定需要一个过程,所以在设置时钟来源时要等待切换成功,对于系统时钟SYCCLK的时钟源的切换,其等待位为寄存器RCC_CFGR的bit[3:2]位。当bit[3:2]=10时说明PLL作系统时钟已经准备好。
RCC_CFGR &= ~(3<<0); //清零
RCC->CFGR |= 2<<0; //选择主PLL作为系统时钟
while((RCC->CFGR&(3<<2))!=(2<<2)); //等待主PLL作为系统时钟成功
为各模块选择时钟源或者配置相应的预分频器时所进行的选择可能会造成干扰,建议仅在复位后但在使能外部振荡器和PLL之前进行选择时钟源选择或配置预分频器等操作。
5 系统时钟输出时钟源
bit[7:4]用于配置 AHB 预分频器的分频系数,系统时钟经过AHB分频后输出的时钟供5大模块使用:
- 送给AHB总线(Advanced High performance Bus,高级高性能总线)、内核、内存和DMA使用的HCLK时钟。由于一般情况下AHB不分频,所以HCLK的频率与Sysclk的相同,都是168Mhz;
- 8分频后送给STM32的系统定时器作为它的时钟源,也即Systick时钟;
- 直接送给Cortex的自由运行时钟FCLK(free running clock),FCLK为处理器的自由振荡的处理器时钟,用来采样中断和为调试模块计时,也是CPU的主频,它不来自于HCLK,因此HCLK停止时FCLK继续运行。FCLK和HCLK互相同步,故两者频率相同,也等于168MHz;
- 送给APB(Advanced Peripheral Bus,先进外围总线)低速预分频器(APB1预分频器),APB1分频器的分频系数可选择1、2、4、8、16分频(由RCC_CFGR中的bit[12:10]决定),其输出的一路供APB1的外设使用(频率为PCLK1,最大频率为42Mhz),另一路送给一部分定时器的倍频器使用。
初始化时钟
/*使能高速外部时钟 HSE 作为系统时钟源,开启 PLL 锁相环*/
uint8_t Sys_Clock_Set(uint32_t plln,uint32_t pllm,uint32_t pllp,uint32_t pllq)
{
uint16_t retry=0;
uint8_t status=0;
RCC_CR |= 1<<16; //HSE 开启
while(((RCC_CR&(1<<17))==0)&&(retry<0X1FFF)) retry++;//等待 HSE RDY
if(retry==0X1FFF) status=1; //HSE 无法就绪
else
{
RCC_APB1ENR |= 1<<28; //电源接口时钟使能
PWR_CR |= 3<<14; //高性能模式,时钟可到 168Mhz
RCC_CFGR |= (0<<4)|(5<<10)|(4<<13);//HCLK 不分频;APB1 4 分频;APB2 2 分频.
RCC_CR &= ~(1<<24); //关闭主 PLL
RCC_PLLCFGR = pllm|(plln<<6)|(((pllp>>1)-1)<<16)|(pllq<<24)|(1<<22);//配置 PLL
RCC_CR |= 1<<24; //打开主 PLL
while((RCC_CR & (1<<25))==0);//等待 PLL 准备好
FLASH_ACR |= 1<<8; //指令预取使能.
FLASH_ACR |= 1<<9; //指令 cache 使能.
FLASH_ACR |= 1<<10; //数据 cache 使能.
FLASH_ACR |= 5<<0; //5 个 CPU 等待周期.
RCC_CFGR &= ~(3<<0); //清零
RCC_CFGR |= 2<<0; //选择主 PLL 作为系统时钟
while((RCC_CFGR&(3<<2))!=(2<<2));//等待主 PLL 作为系统时钟成功. }return status;
}
return status;
}
/*系统时钟初始化函数定义*/
void Stm32_Clock_Init(uint32_t plln,uint32_t pllm,uint32_t pllp,uint32_t pllq)
{
RCC_CR |= 1<<0; //设置 HSISON,开启内部高速 RC 振荡
RCC_CFGR = 0x00000000; //CFGR 清零
RCC_CR &=0xFEF6FFFF; //HSEON,CSSON,PLLON 清零
RCC_PLLCFGR=0x24003010; //PLLCFGR 恢复复位值
RCC_CR &= ~(1<<18); //HSEBYP 清零,外部晶振不旁路
RCC_CIR =0x00000000; //禁止 RCC 时钟中断
Sys_Clock_Set(plln,pllm,pllp,pllq);//设置时钟
}