第二章:SetSysClock系统设置时钟函数详解

static void SetSysClock(void)
{
#if defined (STM32F40_41xxx) || defined (STM32F427_437xx) || defined (STM32F429_439xx) || defined (STM32F401xx)
/******************************************************************************/
/*            PLL (clocked by HSE) used as System clock source                */
/******************************************************************************/
  __IO uint32_t StartUpCounter = 0, HSEStatus = 0;
    
/* Enable HSE */
  /* 使能HSE */ 
RCC->CR |= ((uint32_t)RCC_CR_HSEON);//bit16,HSEON置1即HSE振荡器打开
 
//解析:不断读取HSERDY的状态,当HSE时钟已经就绪了,bit17,HSERDY置1时就会跳出循环,
//或时钟启动超时也跳出循环。这个超时量被设置为0x05000,每次循环就会自增,超过这个值之前,
//HSERDY还没置1,退出循环。退出循环后,判断HSERDY的状态,就绪则为1,否则为0;
/* Wait till HSE is ready and if Time out is reached exit */
/* 等待HSE稳定 */ 
do
{
HSEStatus = RCC->CR & RCC_CR_HSERDY;//bit17,HSERDY即HSE振荡器就绪标志
StartUpCounter++;
} while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));// 等待外部时钟稳定


if ((RCC->CR & RCC_CR_HSERDY) != RESET)//==1
{
HSEStatus = (uint32_t)0x01;
}
else
{
HSEStatus = (uint32_t)0x00;  
}


  if (HSEStatus == (uint32_t)0x01)//==1
  {
    isHseHsiCntFlag |=0x01;
Hse1Hsi0User = 1;
PLL_M = SET_PLL_M;
    /* Select regulator voltage output Scale 1 mode */
    RCC->APB1ENR |= RCC_APB1ENR_PWREN;//bit28,PWREN置1即打开APB1时钟的电源
    PWR->CR |= PWR_CR_VOS;//应该是PWR_CR_VOS_0才对,主要是PWR_CR_VOS把bit15置1,而手册上说bit15~31保留,必须保持复位值。bit14,VOS置1,设置性能与功耗的平衡


    /* HCLK = SYSCLK / 1*/
    RCC->CFGR |= RCC_CFGR_HPRE_DIV1;//bit4~7,HPRE是AHB预分频(当使用以网时,AHB时钟频率至少为25MHz),不分频


#if defined (STM32F40_41xxx) || defined (STM32F427_437xx) || defined (STM32F429_439xx)  
                // 主频修改 
// APB分频修改
//#if (SYS_CORE_CLK_168M1_84M0_USER)             // 修正分别84MHz和168MHz时的PCLK2, PCLK1的分频值
//    //168MHz时,APB1=42MHz,APB2=84MHz
//    /* PCLK2 = HCLK / 2*/
//    RCC->CFGR |= RCC_CFGR_PPRE2_DIV2;//bit13~15,PPRE2是APB高速预分频器(APB2,最大84MHz)
//    
//    /* PCLK1 = HCLK / 4*/
//    RCC->CFGR |= RCC_CFGR_PPRE1_DIV4;//bit10~12,PPRE1是APB低速预分频器(APB1,最大42MHz)
//#else
//   //84MHz时,APB1=42MHz,APB2=84MHz
//    /* PCLK2 = HCLK / 1*/
 //   RCC->CFGR |= RCC_CFGR_PPRE2_DIV;//bit13~15,PPRE2是APB高速预分频器(APB2,最大84MHz)    
 //    /* PCLK1 = HCLK / 2*/
 //    RCC->CFGR |= RCC_CFGR_PPRE1_DIV;//bit10~12,PPRE1是APB低速预分频器(APB1,最大42MHz)
 //#endif /* SYS_CORE_CLK_168M1_84M0_USER */
    /* PCLK2 = HCLK / 2*/
    RCC->CFGR |= RCC_CFGR_PPRE2_DIV;//bit13~15,PPRE2是APB高速预分频器(APB2,最大84MHz)
    
    /* PCLK1 = HCLK / 4*/
    RCC->CFGR |= RCC_CFGR_PPRE1_DIV;//bit10~12,PPRE1是APB低速预分频器(APB1,最大42MHz)


// END
#endif /* STM32F40_41xxx || STM32F427_437x || STM32F429_439xx */


#if defined (STM32F401xx)
    /* PCLK2 = HCLK / 2*/
    RCC->CFGR |= RCC_CFGR_PPRE2_DIV1;//不分频
    
    /* PCLK1 = HCLK / 4*/
    RCC->CFGR |= RCC_CFGR_PPRE1_DIV2;//2分频
#endif /* STM32F401xx */
   
    //配置主PLL的参数,系统时钟SYSCLK;锁相环压腔振荡器时钟PLL_VCO;
    //USB,SD卡,OTG FS时钟为使 USB OTG FS 能够正常工作,需要 48 MHz 的时钟。对于 SDIO 和随即数生成器,频率需要低于或等于 48 MHz 才可正常工作。
  //SYSCLK(最大168MHz)、PLL_VCO(192~432MHz)、HSE_VALUE / PLL_M(1~2MHz,建议2MHz)、PLL_M(2~63)、PLL_P(2、4、6、8)、PLL_N(192~432)
    //PLL_Q(2~15)


    //计算公式:
    //USB,SD卡时钟 = PLL_VCO / PLL_Q
//SYSCLK = PLL_VCO / PLL_P         
//PLL_VCO = (HSE_VALUE / PLL_M) * PLL_N 


//例如1:外部晶振HSE_VALUE=25MHz,PLL_M=25,PLL_N=336,PLL_P=2;
//则系统时钟为168MHz,HCLK不分频为168MHz;PLCK2=84MHz;PCLK1=42MHz;USB,SD卡,OTG FS时钟频率为48MHz


    //例如2:外部晶振HSE_VALUE=8MHz,PLL_M=8,PLL_N=336,PLL_P=2;
//则系统时钟为168MHz࿰
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值