STM32F4 時鍾樹概述


STM32F4 相對於 STM32F1 來說,時鍾部分復雜了很多, STM32F4 的時鍾配置,我們提供兩個函數: Sys_Clock_Set Stm32_Clock_Init。其中 Sys_Clock_Set 是核心的系統時鍾配置函
數,由 Stm32_Clock_Init 調用,實現對系統時鍾的配置。外部程序,一般調用 Stm32_Clock_Init函數來配置時鍾。 sys文件夾中

STM32F4 中,有 5 個最重要的時鍾源,為 HSIHSELSILSEPLL。 其中 PLL 實際是分為兩個時鍾源,分別為主 PLL 和專用 PLL。 從時鍾頻率來分可以分為高速時鍾源和低速
時鍾源,在這 5 個中 HSIHSE 以及 PLL 是高速時鍾, LSI LSE 是低速時鍾。從來源可分為外部時鍾源和內部時鍾源,外部時鍾源就是從外部通過接晶振的方式獲取時鍾源,其中 HSE
LSE 是外部時鍾源,其他的是內部時鍾源。

①、 LSI 是低速內部時鍾, RC 振盪器,頻率為 32kHz 左右。 供獨立看門狗和自動喚醒單元使用。
②、 LSE 是低速外部時鍾,接頻率為 32.768kHz 的石英晶體。 這個主要是 RTC 的時鍾源。
③、 HSE 是高速外部時鍾,可接石英/陶瓷諧振器,或者接外部時鍾源,頻率范圍為 4MHz~26MHz
我們的開發板接的是 8M 的晶振。 HSE 也可以直接做為系統時鍾或者 PLL 輸入。
④、 HSI 是高速內部時鍾, RC 振盪器, 頻率為 16MHz。 可以直接作為系統時鍾或者用作 PLL
輸入。
⑤、 PLL 為鎖相環倍頻輸出。 STM32F4 有兩個 PLL:
1) 主 PLL(PLL)HSE 或者 HSI 提供時鍾信號,並具有兩個不同的輸出時鍾。
第一個輸出 PLLP 用於生成高速的系統時鍾(最高 168MHz
第二個輸出 PLLQ 用於生成 USB OTG FS 的時鍾(48MHz),隨機數發生器的時鍾和 SDIO
時鍾。
2) 專用 PLL(PLLI2S)用於生成精確時鍾,從而在 I2S 接口實現高品質音頻性能。

STM32F4 的時鍾樹圖(非常重要)

 

 

上圖從左往右看,就是整個 STM32F4 的時鍾走向。這里,我們挑選出 9 個重要的地方進行介紹(圖 5.2.2.1 中標出的①~⑨)。
① 這是進入 PLL 之前的一個時鍾分頻系數(M),取值范圍是: 2~63,一般取 8。注意,這個分頻系數,對主 PLL PLLI2S 都有效。
② 這是 STM32F4 的主 PLL,該部分控制 STM32F4 的主頻率(PLLCLK)和 USB/SDIO/隨機數發生器等外設的頻率(PLL48CK)。其中, N 是主 PLL vco 的倍頻系數,其取值
范圍是: 64~432P 是系統時鍾的主 PLL 分頻系數,其取值范圍是: 246 8(僅 限這四個值); Q USB/SDIO/隨機數產生器等的主 PLL 分頻系數,其取值范圍是:
2~15R 沒用到。
③ 這是 STM32F4 I2S 部分的 PLL,該部分主要用於設置 STM32F4 I2S 內部輸入時鍾頻率。其中, N 是用於 PLLI2S vco 的倍頻系數,其取值范圍是: 192~432R I2S 時鍾的分
頻系數,其取值范圍是: 2~7P Q 沒用到。
④ 這是 PLL 之后的系統主時鍾(PLLCLK), STM32F4 的主頻最高是 168Mhz,所以我們一般設置 PLLCLK 168Mhz(M=8,N=336,P=2),通過 SW 選擇 SYSCLK=PLLCLK
即可得到 168Mhz 的系統運行頻率。
⑤ 這是 PLL 之后的 USB/SDIO/隨機數發生器時鍾頻率,由於 USB 必須是 48Mhz 才可以正常工作,所以這個頻率一般設置為 48Mhz(M=8,N=336,Q=7)
⑥ 是 I2S 的時鍾,通過 I2SSRC 選擇內部 PLLI2SCLK 還是外部 I2SCKIN 作為時鍾。 探索者 STM32F4 開發板使用的是內部 PLLI2SCLK
⑦ 這是 Cortex 系統定時器,也就是 SYSTICK 的時鍾。上圖清楚的表明 SYSTICK 的來源是 AHB 分頻后再 8 分頻(這個 8 分頻是可以設置的,即 8 分頻,或者不分頻,一般使
8 分頻), 我們一般設置 AHB 不分頻,則 SYSTICK 的頻率為: 168M/8=21Mhz。前面介紹的延時函數,就是基於 SYSTICK 來實現的。
⑧ 這里是 STM32F4 很多外設的時鍾來源,即兩個總線橋: APB1 APB2,其中 APB1是低速總線(最高 42Mhz), APB2 是高速總線(最高 84Mhz)。另外定時器部分,如
果所在總線(APB1/APB2)的分頻系數為 1,那么就不倍頻,如果不為 1(比如 2/4/8/16),那么就會 2 倍頻(Fabpx*2)后,作為定時器時鍾輸入。
⑨ 這是 STM32F4 內部以太網 MAC 時鍾的來源。對於 MII 接口來說,必須向外部 PHY芯片提供 25Mhz 的時鍾,這個時鍾,可以由 PHY 芯片外接晶振,或者使用 STM32F4
MCO 輸出來提供。然后, PHY 芯片再給 STM32F4 提供 ETH_MII_TX_CLK ETH_MII_RX_CLK 時鍾。對於 RMII 接口來說,外部必須提供 50Mhz 的時鍾驅動 PHY
STM32F4 ETH_RMII_REF_CLK,這個 50Mhz 時鍾可以來自 PHY、有源晶振或者 STM32F4 MCO。 我們的開發板使用的是 RMII 接口,使用 PHY 芯片提供 50Mhz
時鍾驅動 STM32F4 ETH_RMII_REF_CLK
關於時鍾的詳細介紹,在《STM32F4xx 中文參考手冊》第 6.2 節(106~113 頁)有詳細介紹。有不明白的地方,可以對照手冊仔細研究。 最后,提醒下大家, STM32F4 默認的情況下
(比如串口 IAP 時或未初始化時鍾時),使用的是內部 16M HSI 作為時鍾的,所以不需要外部晶振也可以下載和運行代碼的。
從上圖可以看出 STM32F4 的時鍾設計的比較復雜,各個時鍾基本都是可控的,任何外設都有對應的時鍾控制開關,這樣的設計,對降低功耗是非常有用的,不用的外設不開啟時鍾,
就可以大大降低其功耗。
下面開始 Sys_Clock_Set 函數的介紹, 該函數用於配置 STM32F4 的時鍾,包括系統主時鍾、USB/SDIO/隨機數發生器時鍾、 APB1 APB2 時鍾等。 該函數代碼如下:

//時鍾設置函數
//Fvco=Fs*(plln/pllm);
//Fsys=Fvco/pllp=Fs*(plln/(pllm*pllp));
//Fusb=Fvco/pllq=Fs*(plln/(pllm*pllq));
//Fvco:VCO 頻率
//Fsys:系統時鍾頻率
//Fusb:USB,SDIO,RNG 等的時鍾頻率
//Fs:PLL 輸入時鍾頻率,可以是 HSI,HSE 等.
//plln:主 PLL 倍頻系數(PLL 倍頻),取值范圍:64~432.
//pllm:主 PLL 和音頻 PLL 分頻系數(PLL 之前的分頻),取值范圍:2~63.
//pllp:系統時鍾的主 PLL 分頻系數(PLL 之后的分頻),取值范圍:2,4,6,8.(僅限這 4 個值!)
//pllq:USB/SDIO/隨機數產生器等的主 PLL 分頻系數(PLL 之后的分頻),取值范圍:2~15.
//外部晶振為 8M 的時候,推薦值:plln=336,pllm=8,pllp=2,pllq=7.
//得到:Fvco=8*(336/8)=336Mhz
// Fsys=336/2=168Mhz
// Fusb=336/7=48Mhz
//返回值:0,成功;1,失敗。
u8 Sys_Clock_Set(u32 plln,u32 pllm,u32 pllp,u32 pllq)
{
u16 retry=0;
u8 status=0;
RCC->CR|=1<<16; //HSE 開啟
while(((RCC->CR&(1<<17))==0)&&(retry<0X1FFF))retry++;//等待 HSE RDY
if(retry==0X1FFF)status=1; //HSE 無法就緒
else
{
RCC->APB1ENR|=1<<28; //電源接口時鍾使能
PWR->CR|=3<<14; //高性能模式,時鍾可到 168Mhz
RCC->CFGR|=(0<<4)|(5<<10)|(4<<13);//HCLK 不分頻;APB1 4 分頻;APB2 2 分頻.
RCC->CR&=~(1<<24); //關閉主 PLL
RCC->PLLCFGR=pllm|(plln<<6)|(((pllp>>1)-1)<<16)|(pllq<<24)|(1<<22);
//配置主 PLL,PLL 時鍾源來自 HSE
RCC->CR|=1<<24; //打開主 PLL
while((RCC->CR&(1<<25))==0);//等待 PLL 准備好
FLASH->ACR|=1<<8; //指令預取使能.
FLASH->ACR|=1<<9; //指令 cache 使能.
FLASH->ACR|=1<<10; //數據 cache 使能.
FLASH->ACR|=5<<0; //5 個 CPU 等待周期.
RCC->CFGR&=~(3<<0); //清零
RCC->CFGR|=2<<0; //選擇主 PLL 作為系統時鍾
while((RCC->CFGR&(3<<2))!=(2<<2));//等待主 PLL 作為系統時鍾成功.
}
return status;
}

Sys_Clock_Set 函數中,我們設置了 APB1 4 分頻, APB2 2 分頻, HCLK 不分頻,同時選擇 PLLCLK 作為系統時鍾。該函數有 4 個參數,具體意義和計算方法,見函數前面的說
明。 一般我們推薦設置為: Sys_Clock_Set(336,8,2,7),即可設置 STM32F4 運行在 168Mhz 的頻率下, APB1 42MhzAPB2 84MhzUSB/SDIO/隨機數發生器時鍾為 48Mhz

 

 以上代碼中, RCC FLASH 都是 MDK 定義的一個結構體,包含 RCC/FLASH 相關的寄存器組。其寄存器名與《STM32F4xx 中文參考手冊》 里面定義的寄存器名字是一摸一樣的,所
以在你不明白某個寄存器干什么用的時候,可以到《STM32F4xx 中文參考手冊》里面查找一下,你就可以迅速查到這個寄存器的作用以及每個位所代表的意思。 特別注意,由於 FLASH 速度
遠遠跟不上 CPU 的運行頻率,所以這里我們設置了 FLASH 的等待周期為 5, 很明顯, FLASH會大大拖慢程序的運行,不過 STM32F4 有自適實時存儲器加速器(ART),通過這個加速器,可
以讓 STM32F4 獲得相當於 0 FLASH 等待周期的運行效果。關於 STM32F4 FLASH 以及 ART等的介紹,請大家參考《STM32F4xx 中文參考手冊》第 3.3 節(59 頁開始)。
接下來,我們再看下 Stm32_Clock_Init 函數,該函數代碼如下:

//系統時鍾初始化函數
//plln:主 PLL 倍頻系數(PLL 倍頻),取值范圍:64~432.
//pllm:主 PLL 和音頻 PLL 分頻系數(PLL 之前的分頻),取值范圍:2~63.
//pllp:系統時鍾的主 PLL 分頻系數(PLL 之后的分頻),取值范圍:2,4,6,8.(僅限這 4 個值!)
//pllq:USB/SDIO/隨機數產生器等的主 PLL 分頻系數(PLL 之后的分頻),取值范圍:2~15.
void Stm32_Clock_Init(u32 plln,u32 pllm,u32 pllp,u32 pllq)
{
RCC->CR|=0x00000001; //設置 HISON,開啟內部高速 RC 振盪
RCC->CFGR=0x00000000; //CFGR 清零
RCC->CR&=0xFEF6FFFF; //HSEON,CSSON,PLLON 清零
RCC->PLLCFGR=0x24003010; //PLLCFGR 恢復復位值
RCC->CR&=~(1<<18); //HSEBYP 清零,外部晶振不旁路
RCC->CIR=0x00000000; //禁止 RCC 時鍾中斷
Sys_Clock_Set(plln,pllm,pllp,pllq);//設置時鍾
//配置向量表
#ifdef VECT_TAB_RAM
MY_NVIC_SetVectorTable(1<<29,0x0);
#else
MY_NVIC_SetVectorTable(0,0x0);
#endif
}

該函數主要進行了時鍾配置前的一些設置工作,然后通過調用 Sys_Clock_Set 函數,實現對 STM32F4 的時鍾配置。最后,根據代碼運行的位置( FLASH or SRAM), 調用函數
MY_NVIC_SetVectorTable 進行中斷向量表偏移設置。MY_NVIC_SetVectorTable 函數的代碼如下:

//設置向量表偏移地址
//NVIC_VectTab:基址
//Offset:偏移量
void MY_NVIC_SetVectorTable(u32 NVIC_VectTab,u32 Offset)
{
SCB->VTOR=NVIC_VectTab|(Offset&(u32)0xFFFFFE00);
//設置 NVIC 的向量表偏移寄存器,VTOR 低 9 位保留,即[8:0]保留。
}

該函數是用來配置中斷向量表基址和偏移量,決定是在那個區域。當在 RAM 中調試代碼 的時候,需要把中斷向量表放到 RAM 里面, 這就需要通過這個函數來配置。關於向量表的詳
細介紹請參考《Cortex M3 M4 權威指南》第 4.5.3 節(117 頁)或者《Cortex M3 權威指南》第七章,第 113 頁的向量表一章。 關於 SCB->VTOR 寄存器,請參考《STM32F3 F4 系列 Cortex
M4 內核編程手冊》第 4.4.4 節(212 頁),有詳細描述。

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM