STM32F10x时钟系统
请参考芯片的参考手册
简介
时钟是由电路产生的具有周期性的脉冲信号
- 在STM32中存在五个时钟源,分别是HSI(高速内部时钟),HSE(高速外部时钟),LSI(低速内部时钟),LSE(低速外部时钟),PLL(锁相环倍频)。分类如下所示:
- 根据时钟频率可以分为高速(High Speed)时钟源和低速时钟源。
- 高速时钟源:HSI,HSE,PLL
- 低速时钟源:LSI,LSE
- 根据来源可以划分为外部时钟源和内部时钟源
- 外部时钟源:LSE,HSE
- 内部时钟源:PLL,LSI,HSI
- 如下图所示:几个重要的时钟是SYSCLM(系统时钟),AHB总线时钟,APB1总线时钟(低速,速度最高36MHz),APB2总线时钟(高速,速度最高72MHz),PLL时钟
![]()
- 根据时钟频率可以分为高速(High Speed)时钟源和低速时钟源。
- HSI:由内置的RC振荡器产生,频率近似为8MHz,可直接作为系统时钟或在2分频后作为PLL输入
- HSE:可接晶体/陶瓷谐振器,或者接外部时钟源,频率范围为4MHz~16MHz
- LSI:由内置的RC振荡器产生,频率近似为40kHz。其可以在停机或者待机模式下保持运行
- LSE:接频率为32.768kHz的外部晶体或者陶瓷谐振器
- PLL:用来倍频HSI RC的输出时钟或HSE晶体输出时钟。
时钟配置相关的寄存器
- 时钟配置相关的寄存器如下所示:
- RCC_CR:时钟控制寄存器,HSI,HSE,CSS(时钟监视系统),PLL等的使能和就绪标志位
- RCC_CFGR:时钟配置寄存器,PLL等的时钟源选择,分频系数设定,微控制器时钟输出设定等
- RCC_CIR:时钟中断寄存器,清除/使能时钟就绪中断
- RCC_APB2RSTR:APB2外设复位寄存器,APB2线上外设复位寄存器
- RCC_APB1RSTR:APB1外设复位寄存器,APB1线上外设复位寄存器
- RCC_AHBENR:AHB时钟使能寄存器
- RCC_APB2ENR:APB2外设时钟使能寄存器
- RCC_APB1ENR:APB1外设时钟使能寄存器
- RCC_BDCR:备份域控制寄存器
- RCC_CSR:控制/状态寄存器
- 在MDK中定义如下:
typedef struct
{
__IO uint32_t CR;
__IO uint32_t CFGR;
__IO uint32_t CIR;
__IO uint32_t APB2RSTR;
__IO uint32_t APB1RSTR;
__IO uint32_t AHBENR;
__IO uint32_t APB2ENR;
__IO uint32_t APB1ENR;
__IO uint32_t BDCR;
__IO uint32_t CSR;
} RCC_TypeDef;
时钟配置相关的函数
- 时钟使能配置
- 时钟源相关配置
- 分频系数选择配置
- 外设时钟使能
- 其他外设时钟使能
- 状态参数获取
- RCC中断相关函数
SystemInit函数
- 这个函数很重要,在上一节中也讲到了在复位中断处理程序中会调用。 这个函数主要初始化了系统时钟的频率,HCLK时钟,PCLK2时钟,PCLK1时钟的预分频系数。核心代码如下所示:
#define SYSCLK_FREQ_72MHz 72000000
void SystemInit (void)
{
#ifdef SYSCLK_FREQ_72MHz
__IO uint32_t StartUpCounter = 0, HSEStatus = 0;
RCC->CR |= ((uint32_t)RCC_CR_HSEON); // HSE振荡器(外部高速时钟)开启
// 等待外部高速时钟就绪
do
{
HSEStatus = RCC->CR & RCC_CR_HSERDY;
StartUpCounter++;
} while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
// 外部高速时钟已就绪
if (HSEStatus == (uint32_t)0x01)
{
/* Enable Prefetch Buffer */
FLASH->ACR |= FLASH_ACR_PRFTBE;
/* Flash 2 wait state */
FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY);
FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_2;
/* HCLK = SYSCLK */
RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1; // 计算HCLK(高速AHB的时钟)时,系统时钟不分频
/* PCLK2 = HCLK */
RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1; // 计算PCLK2(高速APB的时钟)时,系统时钟不分频
/* PCLK1 = HCLK / 2 */
RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2; // 计算PCLK1(低速APB的时钟)时,系统时钟二分频
/* PLL configuration: PLLCLK = HSE * 9 = 72 MHz */
RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE |
RCC_CFGR_PLLMULL));
RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLMULL9);
/* Enable PLL */
RCC->CR |= RCC_CR_PLLON; // PLL时钟使能
/* Wait till PLL is ready */
while((RCC->CR & RCC_CR_PLLRDY) == 0)
{
}
/* Select PLL as system clock source */
RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL; // 将PLL输出作为系统时钟
/* Wait till PLL is used as system clock source */
while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x08)
{
}
}
#endif
}
- 经过这个函数初始化后,SYSCLK时钟为72MHz,AHB时钟为72MHz,APB1时钟为36MHz,APB2时钟为72MHz。

浙公网安备 33010602011771号