时钟系统是STM32的核心,系统上电的第一步,就是正确的配置时钟。对于初学者来说,STM32的时钟系统显得有些复杂。不过,我们只要掌握几个重要概念,了解STM32时钟产生路径,就可以轻松搞定STM32的时钟系统。下图是STM32F10xx时钟系统的框图:
一、 几个重要概念:
l 四个时钟源:HSI、HSE、LSI、LSE。
l 五个输出时钟:SYSCLK,HCLK,PCLK1,PCLK2, RTCCLK。
l 两个时钟处理机制:倍频器,预分频器。
1、 四个时钟源:
HIS - 高速内部时钟信号,由STM32内部8MHz的振荡器产生,可直接作为系统时钟或在2分频后作为PLL输入。
HSE - 高速外部时钟信号,由外部晶振产生,支持4~16MHz。
LSI - 低速内部时钟信号,频率约40KHz(30KHz~60KHz之间,精度较差),可以在停机或待机模式下保持运行,为独立看门狗和自动唤醒单元提供时钟。
LSE – 低速外部时钟信号,由一个32.768KHz的低速外部晶振产生,可以为实时时钟或其他定时功能提供低功耗且精确的时钟源。
备注:图中间的CSS是时钟监视系统,确保在外部时钟HSE失效时能自动切换至内部时钟HSI。
2、 五个输出时钟
SYSCLK – 系统时钟,它是STM32处理器最重要的时钟信号。使用HSE作为时钟源时,频率可以高达72MHz。SYSCLK为内核和系统的大部分其他时钟输出提供时钟基础。
HCLK – 高速总线时钟,HCLK为系统AHB总线提供时钟,最高可达72MHz。
PCLK1 – APB1总线时钟,为挂接到APB1总线的外设提供时钟信号,最高可达36MHz。
PCLK2 – APB2总线时钟,为挂接到APB2总线的外设提供时钟信号,最高可达72MHz。
RTCCLK – 实时时钟,如果选择低速外部晶振(32.768KHz),可以为系统提供精确的时基信号,作为系统计时的基础,只要VBAT维持供电,尽管VDD供电被切断,RTC仍继续工作。
3、 两个时钟处理机
倍频器(Multiplier) – 负责将输入的时钟信号,乘以一个数后输出。
预分频器(Prescaler) - 负责将输入信号,除以一个数后输出。
二、 时钟路径
时钟路径:就是输出时钟信号,是通过什么方式由输入时钟源得到的。
其实通过上面的时钟系统框图,我们可以很清楚的看到每个输出时钟的路径,这里就不再做细说,指示对一些关键的地方,做一些解释。
1、 SYSCLK时钟:
SYSCLK时钟可以由三个时钟源产生
l 直接由HSI产生
l 直接由HSE产生
l 有PLLCLK产生
这里需要特别说明由PLLCLK产生的情况,这是我们最常用的一种时钟选择。PLLCLK是由HSI和HSE通过倍频产生的,但是如果是通过HSI产生,HSI会被二分频(4MHz)后,最为PLL的输入,不过需要注意的是,当选取HSI作为时钟源时,由于内部时钟精度和稳定性关系,系统时钟最高只能到36MHz。PLL倍频器可以提供16种倍频系数,比如说我们需要产生72MHz的SYSCLK,那么可以选取8M外部晶振作为时钟源,PLL倍频系数选择为9倍,则8MHz * 9=72MHz。
2、 HCLK时钟:
这里先扫盲一下两个基本概念,AHB和APB,以下文字来自百度文库,已经熟悉的朋友可以跳过:
随着深亚微米工艺技术日益成熟,集成电路芯片的规模越来越大。数字IC从基于时序驱动的设计方法,发展到基于IP复用的设计方法,并在SOC设计中得到了广泛应用。在基于IP复用的SoC(System on Chip的缩写,称为系统级芯片,也有称片上系统)设计中,片上总线设计是最关键的问题。为此,业界出现了很多片上总线标准。其中,由ARM公司推出的AMBA片上总线受到了广大IP开发商和SoC系统集成者的青睐,已成为一种流行的工业标准片上结构。 AMBA规范主要包括了AHB(Advanced High performance Bus)系统总线和APB(Advanced Peripheral Bus)外围总线。
AHB主要用于高性能模块(如CPU、DMA和DSP等)之间的连接,作为SoC的片上系统总线,它包括以下一些特性:单个时钟边沿操作;非三态的实现方式;支持突发传输;支持分段传输;支持多个主控制器;可配置32位~128位总线宽度;支持字节、半字和字的传输。AHB 系统由主模块、从模块和基础结构(Infrastructure)3部分组成,整个AHB总线上的传输都由主模块发出,由从模块负责回应。基础结构则由仲裁器(arbiter)、主模块到从模块的多路器、从模块到主模块的多路器、译码器(decoder)、虚拟从模块(dummy Slave)、虚拟主模块(dummy Master)所组成。
APB主要用于低带宽的周边外设之间的连接,例如UART、1284等,它的总线架构不像AHB支持多个主模块,在APB里面唯一的主模块就是APB 桥。其特性包括:两个时钟周期传输;无需等待周期和回应信号;控制逻辑简单,只有四个控制信号。
了解上面概念后,我们再看下HCLK是怎么产生的。从时钟系统框图可以看出,SYSCLK经过AHB预分频器(AHB Prescaler)后,输出HCLK。假如我们取分频因子为1,则HCLK=72MHz / 1=72MHz。
3、 PCLK时钟
这里需要注意的是,PCLK1最高只能配置为36MHz,其他的看时钟系统框图都容易理解。这里需要解释下那些设备是挂到了APB1总线下,那些是挂到APB2总线下:
从上图可以很清楚的了解到,APB1和APB2下都有那些设备。也就是说,当我们使用APB对饮的设备时,需要正确的配置和打开对饮的PCLK时钟,否则设备是不能被启用的,这和传统51单片机不一样。
STM32时钟系统涉及到的寄存器
在文件“stm32f10x_map.h”中,定义了RCC 寄存器结构RCC_TypeDeff:
/*------------------------ Reset and Clock Control ---------------------------*/ 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;
各个寄存器的具体定义,请参阅《STM32中文参考手册》
STM32时钟初始化函数
/* * 时钟初始化函数 * sysclk:系统时钟,单位MHz * AHB=DIV1,APB1=DIV2,APB2=DIV1 * 注意APB1时钟不可超过36MHz */ void Stm32_SysClk_Init(u8 sysclk) { u8 pllmulti; pllmulti = (sysclk>>3)-2; //计算基于8M时钟源时,PLL的倍频因子 UCTX_RCC_DeInit(); RCC->CR |= 1<<16; //使能外部时钟源HSE while((RCC->CR & 1<<17) == 0); //等待外部时钟源就绪 RCC->CFGR |= pllmulti<<18; //设置PLL倍频 RCC->CFGR |= 4<<8; //AHB=DIV1,APB1=DIV2,APB2=DIV1,注: PCLK1不能超过36MHz RCC->CFGR |= 1<<16; //选择HSE作为PLL时钟源 FLASH->ACR|=0x32; //FLASH 2个延时周期 RCC->CR |= 1<<24; //PLL使能 while((RCC->CR & 1<<25)==0); //等待PLL锁定 RCC->CFGR |= 0x02; //PLL作为系统时钟 while((RCC->CFGR>>2 & 3)!=2); //等待系统时钟切换成功 } void UCTX_RCC_DeInit(void) { RCC->AHBENR = 0x00000014; //睡眠模式闪存和SRAM时钟使能.其他关闭. RCC->APB2ENR = 0x00000000; //外设时钟关闭. RCC->APB1ENR = 0x00000000; RCC->CR |= 1<<0; //使能内部高速时钟HSION //复位SW[1:0],HPRE[3:0],PPRE1[2:0],PPRE2[2:0],ADCPRE[1:0],MCO[2:0] RCC->CFGR &= 0xF8FF0000; RCC->CR &= 0xFEF6FFFF; //复位HSEON,CSSON,PLLON RCC->CR &= 0xFFFBFFFF; //复位HSEBYP RCC->CFGR &= 0xFF80FFFF; //复位PLLSRC, PLLXTPRE, PLLMUL[3:0] and USBPRE RCC->CIR = 0x00000000; //关闭所有时钟中断 }
更多参考源码请到CORTEX技术之家下载。
作者:布谷鸟@UCORTEX
QQ:21073231
技术论坛:www.ucortex.com