stm32學習之路:第七天
阿新 • • 發佈:2019-02-13
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啟動識別,使用者在這裡新增糾錯程式碼 */ }
}