第二章:SetSysClock系统设置时钟函数详解(2)--简化版

static void SetSysClock(void)

{

    //在MDK5中设置部分要添加Define:STM32F40_41xxx,USE_STDPERIPH_DRIVER

    #if defined (STM32F40_41xxx) || defined (STM32F427_437xx) || defined (STM32F429_439xx) || defined (STM32F401xx)

    __IO uint32_t     StartUpCounter = 0,     HSEStatus = 0;

    /* Enable HSE */
    /* 使能HSE */ //#define  RCC_CR_HSEON                        ((uint32_t)0x00010000)
    RCC->CR |= ((uint32_t)RCC_CR_HSEON);        //bit16,HSEON置1即HSE振荡器打开

    do
    {
HSEStatus = RCC->CR & RCC_CR_HSERDY;    //bit17,HSERDY即HSE振荡器就绪标志
StartUpCounter++;

    } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));    // 等待外部时钟稳定

// #define HSE_STARTUP_TIMEOUT    ((uint16_t)0x05000)   /*!< Time out for HSE start up */

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

    }

    else
    {
HSEStatus = (uint32_t)0x00;  

    }

    //volatile uint8_t  isHseHsiCntFlag ; //bit0置1累计外部高速晶振次数,bit1置1累计内部高速晶振次数

    // _at_NO_INIT_ volatile uint8_t  Hse1Hsi0User ;//为1时外部高速晶振,为0时内部高速晶振

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) 

                /* 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)

         #endif    

          /* Configure the main PLL */
           RCC->PLLCFGR = PLL_M | (PLL_N << 6) | (((PLL_P >> 1) -1) << 16) |
                                                       (RCC_PLLCFGR_PLLSRC_HSE) | (PLL_Q << 24);

        /* Enable the main PLL */
        /* 使能主PLL*/ 
        RCC->CR |= RCC_CR_PLLON;        //bit24,PLLON置1即PLL开启

        // 等待主PLL就绪
        /* Wait till the main PLL is ready */
        while((RCC->CR & RCC_CR_PLLRDY) == 0)
        {

        }

        #if defined (STM32F40_41xxx)     
        /* Configure Flash prefetch, Instruction cache, Data cache and wait state */
        FLASH->ACR = FLASH_ACR_PRFTEN | FLASH_ACR_ICEN |FLASH_ACR_DCEN |FLASH_ACR_LATENCY_5WS;
        #endif

        // 设置主PLL时钟为系统时钟源
        /* Select the main PLL as system clock source */
        RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
        RCC->CFGR |= RCC_CFGR_SW_PLL;

        //最后等待时钟稳定,切换成功后退出循环 
        /* Wait till the main PLL is used as system clock source */
        while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS ) != RCC_CFGR_SWS_PLL);
        {

        }

}

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 */
         SetHsiClockUser();
}

}

你可能感兴趣的:(第二章:SetSysClock系统设置时钟函数详解(2)--简化版)