前言
本系列文章統(tǒng)一圍繞STM32F103C8T6最小系統(tǒng)開發(fā)板進(jìn)行記錄,如涉及其他開發(fā)板將會特別說明窄俏。
STM32時鐘的概念
時鐘對于STM32而言是驅(qū)動源,相當(dāng)于人類的心臟碘菜。有了時鐘凹蜈,STM32才能運(yùn)行限寞,并給片上的所有外設(shè)模塊提供時鐘使其正常工作。
STM32中系統(tǒng)時鐘為什么有這么多的時鐘源仰坦?
- 提供STM32系統(tǒng)內(nèi)核履植、各種總線和外設(shè)所需要的工作頻率。
- 增加抗電磁干擾能力缎岗,提高穩(wěn)定性静尼。
- 考慮掉電情況(外部高/低速時鐘無法正常供電時,內(nèi)部高/低速時鐘可以提供時鐘源)传泊。
時鐘源
以stm32f1系列為例:
-
外部高速時鐘(HSE)
- 來源:可接石英 / 陶瓷諧振器,或者接外部時鐘源鸭巴。
- 頻率范圍是 4MHz – 16MHz眷细。
- 可以直接作為系統(tǒng)時鐘或PLL輸入。
-
內(nèi)部高速時鐘(HSI)
- 來源:內(nèi)部RC振蕩器鹃祖。
- 頻率為8MHz(用此時鐘源溪椎,系統(tǒng)時鐘SYSCLK的最大頻率不超過64MHz,8/2*16 = 64MHz)恬口。
- 可以直接作為系統(tǒng)時鐘或PLL輸入校读。
-
外部低速時鐘(LSE)
- 來源:外接石英晶體。
- 頻率為 32.768KHz祖能。
- 主要是RTC的時鐘源歉秫。
-
內(nèi)部低速時鐘(LSI)
- 來源:內(nèi)部RC 振蕩器。
- 頻率為 40KHz左右(30K-60KHz)养铸。
- 供獨(dú)立看門狗和自動喚醒單元使用雁芙。
-
鎖相環(huán)時鐘(PLL):鎖相環(huán)倍頻輸出,可作為系統(tǒng)的時鐘源钞螟,嚴(yán)格的來說并不算一個獨(dú)立的時鐘源兔甘。
- 來源:HSI/2 、 HSE 或者 HSE/2 鳞滨。
- PLL倍頻因子:2 – 16 倍洞焙。
- 輸出頻率最大不得超過 72MHz。
-
系統(tǒng)時鐘源(SYSTICK):
- 最大頻率為72MHz拯啦。
- 來源:PLL倍頻輸出澡匪、HSI或者HSE。
- 輸出:AHB分頻器提岔。
-
AHB總線時鐘(HCLK):將系統(tǒng)時鐘頻率進(jìn)行分頻并提供給各模塊使用仙蛉。
- 分頻因子:1、2碱蒙、4荠瘪、8夯巷、16、64哀墓、128趁餐、256、512篮绰。
- 主要輸出:
- AHB總線后雷、內(nèi)核、內(nèi)存和DMA使用的HCLK時鐘吠各。
- 通過8分頻后送給Cortex的系統(tǒng)定時器時鐘臀突。
- Cortex的自由運(yùn)行時鐘FCLK。
- APB1預(yù)分頻器贾漏。
- APB2預(yù)分頻器 候学。
-
APB1總線時鐘(PCLK1):低速總線時鐘,最大為36MHz纵散。
- 來源:由AHB分頻而得梳码。
- 分頻因子:1、2伍掀、4掰茶、8、16蜜笤。
- 輸出:APB1外設(shè)濒蒋、通用定時器2~7。
-
APB2總線時鐘(PCLK2):高速總線時鐘瘩例,最大為72MHz啊胶。
- 來源:由AHB分頻而得。
- 分頻因子:1垛贤、2焰坪、4、8聘惦、16某饰。
- 輸出:APB2外設(shè)、高級定時器1和定時器8善绎。
RCC寄存器
-
RCC_CR 時鐘控制寄存器
- 內(nèi)外部高速時鐘的使能和就緒標(biāo)志(含內(nèi)部高速時鐘校準(zhǔn)調(diào)整)黔漂。
- 外部高速時鐘旁路。
- 時鐘安全系統(tǒng)CSS使能禀酱。
- PLL使能和PLL就緒標(biāo)志炬守。
-
RCC_CFGR 時鐘配置寄存器
- 系統(tǒng)時鐘源切換及狀態(tài)。
- AHB剂跟、APB1减途、APB2酣藻、ADC、USB預(yù)分頻選擇鳍置。
- PLL輸入時鐘源選擇及HSE輸入PLL分頻選擇辽剧,PLL倍頻系數(shù)選擇。
- MCO(PA8)引腳微控制器時鐘輸出税产。
-
RCC_APBxRSTR 外設(shè)復(fù)位寄存器
- LSI怕轿、LSE、HIS辟拷、HSE撞羽、PLL就緒中斷標(biāo)志。
- HSE時鐘失效導(dǎo)致時鐘安全系統(tǒng)中斷標(biāo)志衫冻。
- LSI放吩、LSE、HIS羽杰、HSE、PLL就緒中斷使能到推。
- 清除LSI考赛、LSE、HIS莉测、HSE颜骤、PLL就緒中斷。
- 清除時鐘安全系統(tǒng)中斷捣卤。
-
RCC_AHBENR/APBxENR外設(shè)時鐘使能寄存器
- 主要功能:使能AHB忍抽、APB1、APB2總線下的各外設(shè)
-
RCC_APBxRSTR 外設(shè)復(fù)位寄存器
- 主要功能:APB1董朝、APB2總線下的各外設(shè)復(fù)位
系統(tǒng)時鐘的配置
以stm32f1系列為例:官方提供的啟動文件startup_stm32f10x_hd.s中鸠项,在執(zhí)行main函數(shù)前會調(diào)用system_stm32f10x.c文件下的SystemInit函數(shù)對系統(tǒng)時鐘進(jìn)行配置。
在SystemInit函數(shù)下的SetSysClock函數(shù)子姜,會對系統(tǒng)時鐘頻率祟绊、HCLK、PCLK等進(jìn)行具體配置哥捕。
/**
* @brief Configures the System clock frequency, HCLK, PCLK2 and PCLK1 prescalers.
* @param None
* @retval None
*/
static void SetSysClock(void)
{
#ifdef SYSCLK_FREQ_HSE
SetSysClockToHSE();
#elif defined SYSCLK_FREQ_24MHz
SetSysClockTo24();
#elif defined SYSCLK_FREQ_36MHz
SetSysClockTo36();
#elif defined SYSCLK_FREQ_48MHz
SetSysClockTo48();
#elif defined SYSCLK_FREQ_56MHz
SetSysClockTo56();
#elif defined SYSCLK_FREQ_72MHz
SetSysClockTo72();
#endif
設(shè)置系統(tǒng)時鐘頻率為72MHz的基本流程:
- 使能HSE時鐘并等待完成牧抽。
/* Enable HSE */
RCC->CR |= ((uint32_t)RCC_CR_HSEON);
/* Wait till HSE is ready and if Time out is reached exit */
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;
}
- 設(shè)置HCLK、PCLK1遥赚、PCLK2頻率扬舒。
/* HCLK = SYSCLK */
RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;
/* PCLK2 = HCLK */
RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1;
/* PCLK1 = HCLK */
RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2;
- 使能PLL鎖相環(huán)時鐘并設(shè)置倍頻因子為9(9*8MHz = 72MHz),使能并選擇其為系統(tǒng)的時鐘源凫佛。
/* PLL configuration: PLLCLK = HSE * 9 = 72 MHz */
RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE |
RCC_CFGR_PLLMULL));
RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLMULL9);
/* Enable PLL */
RCC->CR |= RCC_CR_PLLON;
/* Wait till PLL is ready */
while((RCC->CR & RCC_CR_PLLRDY) == 0)
{
}
/* Select PLL as system clock source */
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 */
while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x08)
{
}
至此讲坎,成功將系統(tǒng)時鐘頻率設(shè)置為72MHz孕惜,其中PCLK1為36MHz,PCLK2為72MHz衣赶。