stm32专题五:时钟树(二)系统配置时钟函数分析
2021-10-15 来源:eefocus
分析stm32的系统时钟函数,对于我们实现自定义时钟配置非常重要,以下是标准库函数中的时钟配置函数。
static void SetSysClockTo72(void)
{
__IO uint32_t StartUpCounter = 0, HSEStatus = 0;
/* SYSCLK, HCLK, PCLK2 and PCLK1 configuration ---------------------------*/
/* Enable HSE */
// 使能HSE
RCC->CR |= ((uint32_t)RCC_CR_HSEON);
/* Wait till HSE is ready and if Time out is reached exit */
// 等待HSE就绪并做超时处理
do
{
HSEStatus = RCC->CR & RCC_CR_HSERDY;
StartUpCounter++;
} while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
/* 分析:当不超过超时时间时,后面这部分一直为1;因此,只要HSERDY了,立马跳出循环
如果HSE故障,则会一直等到设定的超时时间,然后跳出 */
// 上面只是跳出循环,这里判断HSE是否真正启动成功
if ((RCC->CR & RCC_CR_HSERDY) != RESET)
{
HSEStatus = (uint32_t)0x01;
}
else
{
HSEStatus = (uint32_t)0x00;
}
// HSE启动成功,程序继续往下执行
if (HSEStatus == (uint32_t)0x01)
{
/* Enable Prefetch Buffer */
// 使能预取指,CPU运行过程:取指令-执行指令-取指令-执行指令
// 预取指类似于8086的指令队列,会取出当前和接下来要执行的多条指令,送入指令队列缓冲
FLASH->ACR |= FLASH_ACR_PRFTBE;
/* Flash 2 wait state */
/* CPU从Flash取指令的时间间隔,72MHz时要等待两个时钟周期
等待的原因时,flash运行速度慢,CPU如果一直等待flash就绪,则会浪费很多时间效率低下
因此等待两个时钟周期,待flash就绪然后读取指令到预取指缓存 */
FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY);
FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_2;
// 配置AHB APB1 APB2总线的分频因子
/* HCLK = SYSCLK = 72M*/
RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;
/* PCLK2 = HCLK = 72M */
RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1;
/* PCLK1 = HCLK = 36M */
RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2;
/* PLL configuration: PLLCLK = HSE * 9 = 72 MHz */
// 配置锁相环输入为HSE不分频
RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE |
RCC_CFGR_PLLMULL));
// 配置PLL倍频因子为9
RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLMULL9);
/* Enable PLL */
// 使能PLL锁相环
RCC->CR |= RCC_CR_PLLON;
/* Wait till PLL is ready */
// 等待锁相环准备就绪
while((RCC->CR & RCC_CR_PLLRDY) == 0)
{
}
/* Select PLL as system clock source */
// 选择PLLCLK作为系统时钟
RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL;
/* Wait till PLL is used as system clock source */
// 等待PLLCLK切换成功
while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x08)
{
}
}
// 如果HSE启动失败,在这里填入错误处理代码
else
{ /* If HSE fails to start-up, the application will have wrong clock
configuration. User can add here some code to deal with this error */
}
}
上一篇:STM32时钟树解析
下一篇:STM32系统时钟树分析