外設(shè)需要工作也需要時鐘驅(qū)動,通過多路選擇器以及對應(yīng)的寄存器配置初始化最適合的外設(shè)頻率可以讓外設(shè)更高頻的工作。

從上面截圖以及紅框中可以看到,外設(shè)時鐘根PERCLK_CLK_ROOT與IPG_CLK_ROOT為大多數(shù)常用的外設(shè)提供時鐘,初始化這兩個時鐘根需要先對AHB_CLK_ROOT進(jìn)行初始化
初始化AHB_CLK_ROOT
AHB_CLK_ROOT的時鐘來源在CBCDR[PERIPH_CLK_SEL]處有一個多路選擇器

從上面這個圖可以看出AHB_CLK_ROOT最大支持的頻率是132MHz,如果在CBCDR[PERIPH_CLK_SEL]這個多路選擇器這里選擇了上路,那它的時鐘來源最大的頻率是PLL3_480,通過CBCDR[PERIPH_CLK2_RODF]分頻后最大只能到120(此時分頻器的值是4,如果是3的話160則超過了最大值),因為AHB_CLK_ROOT限制最大是132。因此CBCDR[PERIPH_CLK_SEL]這個多路選擇器,選擇下路, 同時在CBCMR[PRE_PERIPH_CLK_SEL]時選擇PLL2的PFD2時鐘源,它的時鐘頻率是396MHz,最終達(dá)到AHB_CLK_ROOT時經(jīng)過CBCDR[AHB_PODF]分頻器處理剛好得到132MHz的頻率。
/// 配置外接設(shè)備的時鐘頻率
/// CBCMR[PRE_PERIPH_CLK_SEL]選擇PLL2->PFD2
/// 先將19-18兩個bit位清0
/// 再將19-18兩個bit位的數(shù)據(jù)寫成1,選擇PFD2
CCM->CBCMR &= ~(3 << 18);
CCM->CBCMR |= (1 << 18);
/// CBCDR[PERIPH_CLK_SEL]多路選擇器選擇下路
CCM->CBCDR &= ~(1 << 25);
/// 讀取第5個bit位(PERIPH_CLK_ SEL_BUSY),如果是1指示正忙于握手,如果是0表示握手完成
while ((CCM->CDHIPR >> 5) & 0x1);
/* 修改 AHB_PODF 位的時候需要先禁止 AHB_CLK_ROOT 的輸出,但是
* 我沒有找到關(guān)閉 AHB_CLK_ROOT 輸出的的寄存器,所以就沒法設(shè)置。
* 下面設(shè)置 AHB_PODF 的代碼僅供學(xué)習(xí)參考不能直接拿來使用!!
* 內(nèi)部 boot rom 將 AHB_PODF 設(shè)置為了 3 分頻,即使我們不設(shè)置 AHB_PODF, * AHB_ROOT_CLK 也依舊等于 396/3=132Mhz。
*/
#if 0
/// 將CBCDR[AHB_PODF]的12-10三個bit位清0
CCM->CBCDR &= ~(7 << 10);
/// 將CBCDR[AHB_PODF]的值設(shè)置成3,即3分頻
CCM->CBCDR | (2 << 10);
/// 等待忙位檢測通過
while ((CCM->CDHIPR >> 1) & 0x1);
#endif
初始化IPG_CLK_ROOT
IPG_CLK_ROOT的頻率最大值是66MHz,從AHB_CLK_ROOT過來的頻率是132MHz,所以這里只需要將CBCDR[IPG_PODF]分頻器的值設(shè)置成除2即可。
/// 將9-8兩個bit位的數(shù)據(jù)清0
CCM->CBCDR &= ~(3 << 8);
/// 設(shè)置成2分頻
CCM->CBCDR |= (1 << 8);
初始化PERCLK_CLK_ROOT
PERCLK_CLK_ROOT的頻率最大值是66MHz,在CBCDR[IPG_PODF]分頻器的作用下它的頻率已經(jīng)是66MHz了,所以此時只需要將CSCMR1[PERCLK_CLK_SEL]多路選擇器選擇到IPG_CLK_ROOT,將PERCLK_PODF分頻器的值設(shè)置成1分頻即可。
/// CSCMR1[PERCLK_CLK_SEL]選擇ipg clk root
CCM->CSCMR1 &= ~(1 << 6);
/// 將5-0 6個bit位清0,設(shè)置成1分頻,此時已經(jīng)是1分頻了
CCM->CSCMR1 &= ~(0x3F << 0);
以上都初始化完成后IPG_CLK_ROOT與PERCLK_CLK_ROOT兩個時鐘根的頻率就工作在子66MHz,最大的發(fā)揮了SOC的性能,這兩個時鐘根也是大部分外設(shè)的時鐘源。
特別說明
修改 AHB_PODF 位的時候需要先禁止 AHB_CLK_ROOT 的輸出,但是
- 我沒有找到關(guān)閉 AHB_CLK_ROOT 輸出的的寄存器,所以就沒法設(shè)置。
- 下面設(shè)置 AHB_PODF 的代碼僅供學(xué)習(xí)參考不能直接拿來使用!!
- 內(nèi)部 boot rom 將 AHB_PODF 設(shè)置為了 3 分頻,即使我們不設(shè)置 AHB_PODF, * AHB_ROOT_CLK 也依舊等于 396/3=132Mhz。# 外設(shè)時鐘根配置
-
時鐘
+關(guān)注
關(guān)注
11文章
1947瀏覽量
134224 -
外設(shè)
+關(guān)注
關(guān)注
0文章
43瀏覽量
12028 -
多路選擇器
+關(guān)注
關(guān)注
1文章
22瀏覽量
6816
發(fā)布評論請先 登錄
STM32為什么要先開啟外設(shè)時鐘?
STM32基于標(biāo)準(zhǔn)外設(shè)庫的外部中斷配置
STM32L552系統(tǒng)時鐘或外設(shè)時鐘配置錯誤導(dǎo)致系統(tǒng)不穩(wěn)定的原因?怎么解決?
PWM對應(yīng)的外設(shè)時鐘
系統(tǒng)時鐘的相關(guān)配置
STM32F105RBT6是如何使用外部晶振8M去配置外設(shè)時鐘的
為什么那么多外設(shè)選擇內(nèi)部48Mhz RC時鐘作為root?
基于STM32時鐘系統(tǒng)的開發(fā)及配置
STM32的時鐘配置——時鐘樹解析

什么是外設(shè)時鐘根配置
評論