STM32—時鐘樹(結合系統時鐘函數理解)
2021-09-02 來源:eefocus
時鐘樹的概念:
我們可以把MCU的運行比作人體的運行一樣,人最重要的是什么?是心跳! 心臟的周期性收縮將血液泵向身體各處。心臟對于人體好比時鐘對于MCU,微控制器(MCU)的運行要靠周期性的時鐘脈沖來驅動,而這個脈沖的始源往往是由外部晶體振蕩器提供時鐘輸入,最終轉換為多個外部設備的周期性運作。這種時鐘“能量”的傳遞路徑猶如大樹的養分由主干流向個分支,因此稱為時鐘樹。
STM32時鐘:
在STM32中每個外設都有其單獨的時鐘,在使用某個外設之前必須打開該外設的時鐘 ,為什么要這么麻煩來設置每一個外設的時鐘而不是將所有外設的時鐘統一打開?因為STM32的外設繁多,外設的運作所需要的最佳時鐘各不相同,如果所有時鐘同時運行會給MCU帶來極大的負載,所以STM32采取自助餐式的時鐘管理方式——隨用隨開。
STM32時鐘樹系統:
認識STM32的時鐘管理方式后就要對其時鐘樹系統有一個大體的掌握,時鐘樹系統的結構如下,從圖中可以知曉有多少時鐘、時鐘速度為多少、時鐘如何分配等。圖看起來很復雜,但我們只需要大體了解其運作流程即可。
各類時鐘簡括:
1.HSE時鐘(高速外部時鐘):來源為外部無源晶振,通常速度8M。
由RCC_CR時鐘控制寄存器中的16:HSEON控制。
2.HSI時鐘(高速內部時鐘):來源為芯片內部,大小為8M,當HSE故障時,系統時鐘會自動切換到HSI,知道HSE啟動成功,相當于HSE的替補。
由RCC_CR時鐘控制寄存器的位0:HSION控制。
3.PLLCLK(鎖相環時鐘):來源為HSI/2、HSE經過倍頻所得。
由CFGR(時鐘配置寄存器)中PLLXTPRE、PLLMUL控制。
4.SYSCLK(系統時鐘):來源為HSI、HSE、PLLCLK,最高速度為72M。
由CFGR中的SW控制。
5.HCLK(AHB高速總線時鐘):來源由系統時鐘分頻得到,速度最高為72M。
由CFGR中的HPRE控制。
6.PCLK1(APB1低總線時鐘):來源為HCLK分頻得到,速度最高為36M ,為APB1總線上的外設提供時鐘。
由RCC_CFGR時鐘配置寄存器的PPRE1位控制。
7.PCLK2(APB2高總線時鐘):來源為HCLK分頻得到,速度最高為72M,為APB2總線上的外設提供時鐘。
由RCC_CFGR時鐘配置寄存器的PPRE2位控制。
8.RTC時鐘:來源為HSE_RTC(HSE分頻得到)、LSE、LSI,為芯片內部的RTC外設提供時鐘。
由RCC備份域控制寄存器RCC_BDCR中RTCSEL控制。
9.MCO時鐘輸出 :來源為PLLCLK/2、HSE、HSI、SYSCLK,微控制器時鐘輸出引腳,由PA8復用所得。
由CRGR中MCO控制。
系統時鐘配置流程
結合系統時鐘函數進行說明,此處利用HSE作為系統時鐘來源,代碼源于野火教程,由于此代碼是幫助我們熟悉系統時鐘配置流程,故不要求可以run
void HSE_SetSysClock(uint32_t pllmul)
2 {
3 __IO uint32_t StartUpCounter = 0, HSEStartUpStatus = 0;
4
5 // 把 RCC 外設初始化成復位狀態
6 RCC_DeInit();
7
8 //使能 HSE,開啟外部晶振,野火 STM32F103 系列開發板用的是 8M
9 RCC_HSEConfig(RCC_HSE_ON);
10
11 // 等待 HSE 啟動穩定
12 HSEStartUpStatus = RCC_WaitForHSEStartUp();
13
14 // 只有 HSE 穩定之后則繼續往下執行
15 if (HSEStartUpStatus == SUCCESS) {
16 //-----------------------------------------------------------------//
17 // 這兩句是操作 FLASH 閃存用到的,如果不操作 FLASH,這兩個注釋掉也沒影響
18 // 使能 FLASH 預存取緩沖區
19 FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
20
21 // SYSCLK 周期與閃存訪問時間的比例設置,這里統一設置成 2
22 // 設置成 2 的時候, SYSCLK 低于 48M 也可以工作,如果設置成 0 或者 1 的時候,
23 // 如果配置的 SYSCLK 超出了范圍的話,則會進入硬件錯誤,程序就死了
24 // 0: 0 < SYSCLK <= 24M
25 // 1: 24< SYSCLK <= 48M
26 // 2: 48< SYSCLK <= 72M
27 FLASH_SetLatency(FLASH_Latency_2);
28 //-----------------------------------------------------------------//
29
30 // AHB 預分頻因子設置為 1 分頻, HCLK = SYSCLK
31 RCC_HCLKConfig(RCC_SYSCLK_Div1);
32
33 // APB2 預分頻因子設置為 1 分頻, PCLK2 = HCLK
34 RCC_PCLK2Config(RCC_HCLK_Div1);
35
36 // APB1 預分頻因子設置為 2 分頻, PCLK1 = HCLK/2
37 RCC_PCLK1Config(RCC_HCLK_Div2);
38
39 //-----------------設置各種頻率主要就是在這里設置-------------------//
40 // 設置 PLL 時鐘來源為 HSE,設置 PLL 倍頻因子
41 // PLLCLK = 8MHz * pllmul
42 RCC_PLLConfig(RCC_PLLSource_HSE_Div1, pllmul);
43 //-------------------------------------------------------------//零死角玩轉 STM32
—基于野火 F103[MINI]開發板
44 //論壇: www.firebbs.cn 138 / 682 淘寶: https://fire-stm32.taobao.com
45 // 開啟 PLL
46 RCC_PLLCmd(ENABLE);
47
48 // 等待 PLL 穩定
49 while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET) {
50 }
51
52 // 當 PLL 穩定之后,把 PLL 時鐘切換為系統時鐘 SYSCLK
53 RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
54
55 // 讀取時鐘切換狀態位,確保 PLLCLK 被選為系統時鐘
56 while (RCC_GetSYSCLKSource() != 0x08) {
57 }
58 } else {
59 // 如果 HSE 開啟失敗,那么程序就會來到這里,用戶可在這里添加出錯的代碼處理
60 // 當 HSE 開啟失敗或者故障的時候,單片機會自動把 HSI 設置為系統時鐘,
61 // HSI 是內部的高速時鐘, 8MHZ
62 while (1) {
63 }
64 }
65 }
代碼步驟 :
1.開啟HSE,并等待HSE穩定;
2.設置AHB、APB1、APB2的預分頻因子;
3.設置PLL的時鐘來源和倍頻因子;
4.開啟PLL,并等待PLL穩定;
5.把PLLCLK切換為系統時鐘SYSCLK;
6.讀取時鐘切換狀態位,確保PLLCLK被選為系統時鐘。
配置流程圖:
圖中序號1~7對應著系統設置配置的流程
結語:其實只要掌握了配置流程圖中黃色部分的配置流程就已經大半理解STM32的時鐘樹了,剛開始學有點懵逼,但看多了,在心中排練的多了就會慢慢熟悉的。