1. 程式人生 > >stm32學習之路:第七天

stm32學習之路:第七天

rccclkconfig.c檔案

#if 0

/*
 *SetSysClock函式來源於system_stm32f4_xx.c
 */
static void SetSysClock(void)
{
  __IO uint32_t StartUpCounter = 0, HSEStatus = 0;

  
/* =====================1-使能 HSE,並等待HSE啟動完成=========================== */
  /*RCC_CR時鐘控制暫存器,HSEON為該暫存器第16位,使能HSE*/
RCC->CR |= ((uint32_t)RCC_CR_HSEON);

 /*判斷HSE是否啟動完畢,HSERDY為RCC_CR時鐘控制暫存器第17位,達到一定時間後也會退出*/
  do
  {
    HSEStatus = RCC->CR & RCC_CR_HSERDY;
    StartUpCounter++;
  } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));




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



  if (HSEStatus == (uint32_t)0x01)
  {
/*==================================================================================*/
    /* 選擇電壓調節器輸出為模式1 */
/*RCC_APB1ENR外設時鐘使能暫存器,PWREN為第28位,使能電源介面時鐘*/
    RCC->APB1ENR |= RCC_APB1ENR_PWREN;
/*PWR_CR為電源控制暫存器,VOS為14,15位,控制電壓級別*/
    PWR->CR |= PWR_CR_VOS;

/* ===================2-配置 AHB APB2 APB1 匯流排的預分頻因子======================== */
    /* HCLK = SYSCLK / 1*/
    RCC->CFGR |= RCC_CFGR_HPRE_DIV1;


    /* PCLK2 = HCLK / 2*/
    RCC->CFGR |= RCC_CFGR_PPRE2_DIV2;
    
    /* PCLK1 = HCLK / 4*/
    RCC->CFGR |= RCC_CFGR_PPRE1_DIV4;
 /* ====================3-配置 PLL的各種分頻因子,並使能PLL========================= */   
    /* 配置 主 PLL */
    RCC->PLLCFGR = PLL_M | (PLL_N << 6) | (((PLL_P >> 1) -1) << 16) |
                   (RCC_PLLCFGR_PLLSRC_HSE) | (PLL_Q << 24);


    /* 使能 PLL */
/*RCC_CR時鐘控制暫存器,PLLON為第24位,使能主PLL*/
    RCC->CR |= RCC_CR_PLLON;


    /* 等待PLL啟動穩定 */
/*RCC_CR時鐘控制暫存器,PLLRDY為第25位,主PLL時鐘就緒標誌*/
    while((RCC->CR & RCC_CR_PLLRDY) == 0)
    {
    }
 
/*==================================================================================*/
   /* 開啟OVER-Drive模式,為的是達到更高的頻率 */
    PWR->CR |= PWR_CR_ODEN;
    while((PWR->CSR & PWR_CSR_ODRDY) == 0)
    {
    }
    PWR->CR |= PWR_CR_ODSWEN;
    while((PWR->CSR & PWR_CSR_ODSWRDY) == 0)
    {
    }      
    /* 配置 Flash 預取指, 指令快取, 資料快取 和等待週期 */
    FLASH->ACR = FLASH_ACR_PRFTEN | FLASH_ACR_ICEN |FLASH_ACR_DCEN |FLASH_ACR_LATENCY_5WS;


 /* ====================4-選擇系統時鐘來源========================= */   
    /* 選擇主鎖相環時鐘(PLL)作為系統時鐘 */
    /*RCC_CFGR時鐘配置暫存器,SW為第0,1位,系統時鐘切換*/
    RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
    RCC->CFGR |= RCC_CFGR_SW_PLL;


    /* 等待PLLCLH切換稱系統時鐘 */
    /*RCC_CFGR時鐘配置暫存器,SWS為第2,3位,系統時鐘切換狀態*/
    while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS ) != RCC_CFGR_SWS_PLL);
    {
    }
  }
  else
  { 
/* HSE啟動失敗後,使用者糾錯的程式碼 */
  }


}


#endif




/*
 *根據SetSysClock函式寫出可以自己控制系統時鐘函式
 */
// m : 2~63
// n :192~432
// p :2、4、6、8
// q :2~15
// SYSCLK = (HSE/m) * n /p = 25/25 * 432 / 2 = 216M 
// HSE_SetSysClk(25,432,2,7)
void HSE_SetSysClk(uint32_t m,uint32_t n,uint32_t p,uint32_t q)
{
__IO uint32_t HSEStartUpStatus = 0;

/* =====================1-使能 HSE,並等待HSE啟動完成=========================== */
RCC_HSEConfig(RCC_HSE_ON);
HSEStartUpStatus = RCC_WaitForHSEStartUp();

if(HSEStartUpStatus == SUCCESS)
{
/* 選擇電壓調節器輸出為模式1 */
RCC->APB1ENR |= RCC_APB1ENR_PWREN;
    PWR->CR |= PWR_CR_VOS;

/* ===================2-配置 AHB APB2 APB1 匯流排的預分頻因子======================== */
RCC_HCLKConfig(RCC_SYSCLK_Div1);
RCC_PCLK2Config(RCC_HCLK_Div2);
RCC_PCLK1Config(RCC_HCLK_Div4);

/* ====================3-配置 PLL的各種分頻因子,並使能PLL========================= */ 
RCC_PLLConfig(RCC_PLLSource_HSE,m,n,p,q);
RCC_PLLCmd(ENABLE);
while ( ( RCC_GetFlagStatus(RCC_FLAG_PLLRDY) ) == RESET )
{
}

/* 開啟OVER-Drive模式,為的是達到更高的頻率 */
    PWR->CR |= PWR_CR_ODEN;
    while((PWR->CSR & PWR_CSR_ODRDY) == 0)
    {
    }
    PWR->CR |= PWR_CR_ODSWEN;
    while((PWR->CSR & PWR_CSR_ODSWRDY) == 0)
    {
    }      
    /* 配置 Flash 預取指, 指令快取, 資料快取 和等待週期 */
    FLASH->ACR = FLASH_ACR_PRFTEN | FLASH_ACR_ICEN |FLASH_ACR_DCEN |FLASH_ACR_LATENCY_5WS;

/* ====================4-選擇系統時鐘來源========================= */   
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
while((RCC_GetSYSCLKSource()) != 0x08)
{
}
}
else{ /* HSE啟動識別,使用者在這裡新增糾錯程式碼 */ }
}