關于STM32時鐘系統的學習。
首先了解一下STM32的結構和時鐘總線。
//
//
時鐘樹
/*****************************/
在分析時鐘樹的時候,需要結合代碼進行分析。
具體的關于時鐘的代碼在:"system_stm32f4xx.c"中。
其中有這樣的一段描述:
Supported STM32F40xxx devices
*-----------------------------------------------------------------------------
* System Clock source | PLL (HSE)
*-----------------------------------------------------------------------------
* SYSCLK(Hz) | 168000000
*-----------------------------------------------------------------------------
* HCLK(Hz) | 168000000
*-----------------------------------------------------------------------------
* AHB Prescaler | 1 (高性能總線的預分頻數)
*-----------------------------------------------------------------------------
* APB1 Prescaler | 4
*-----------------------------------------------------------------------------
* APB2 Prescaler | 2
*-----------------------------------------------------------------------------
* HSE Frequency(Hz) | 25000000 (ST官方推薦的外部時鐘是25M,不過很多的中國公司選用的是8M)
*-----------------------------------------------------------------------------
* PLL_M | 25 ( M是外部高速時鐘, 剛進來時候分頻的系數)
*-----------------------------------------------------------------------------
* PLL_N | 336 (M分頻之後的,進來的倍數。)
*-----------------------------------------------------------------------------
* PLL_P | 2 (N倍頻之後,再經過P分頻,供給SYSclock 作為系統時鐘)
*-----------------------------------------------------------------------------
* PLL_Q | 7 (這個時外設使能時鐘,48M)
*-----------------------------------------------------------------------------
* PLLI2S_N | NA (以下帶I2S标記的,高品質音頻專用的時鐘)
*-----------------------------------------------------------------------------
* PLLI2S_R | NA
*-----------------------------------------------------------------------------
* I2S input clock | NA
*-----------------------------------------------------------------------------
* VDD(V) | 3.3
*-----------------------------------------------------------------------------
* Main regulator output voltage | Scale1 mode
*-----------------------------------------------------------------------------
* Flash Latency(WS) | 5
*-----------------------------------------------------------------------------
* Prefetch Buffer | ON
*-----------------------------------------------------------------------------
* Instruction cache | ON
*-----------------------------------------------------------------------------
* Data cache | ON
*-----------------------------------------------------------------------------
* Require 48MHz for USB OTG FS, | Disabled
* SDIO and RNG clock |
*=============================================================================
*/
我們根據時鐘樹來分析,sysclock ,系統時鐘是怎麼來的 ?
HSI
HSE
LSI
LSE
PLL
在STM32中,一樣的,都是由五個基本的時鐘源來提供:
1.外部高速時鐘:HSE(大多數的中國企業用的的8M的晶振)
2.内部高速時鐘:HSI(RC振蕩器,頻率為16MHZ,可以直接作為系統時鐘,或者PLL的輸入)
3.外部低速時鐘:LSE(頻率為 32.768kHz 的石英晶體。 這個主要是 RTC 的時鐘源)
4.内部低速時鐘:(RC 振蕩器,頻率為 32kHz 左右。 供獨立看門狗和自動喚醒單元使用)
5.PLL鎖相環輸出,(分為pllp pllq )
其中: system_stm32f4xx.c 中的檔案是配置晶振讓晶片先啟動,從内部的高速時鐘啟動,變換到外部的高速時鐘,PLL倍頻分頻之後,通過配置提供給AHB APB等各種外設,這個配置是通過
stm32f4xx_rcc.h 和 stm32f4xx_rcc.c
來實作的:
那麼去分析下:stm32f4xx_rcc.h 先:
void RCC_AHB1PeriphClockLPModeCmd(uint32_t RCC_AHB1Periph, FunctionalState NewState);
void RCC_AHB2PeriphClockLPModeCmd(uint32_t RCC_AHB2Periph, FunctionalState NewState);
void RCC_AHB3PeriphClockLPModeCmd(uint32_t RCC_AHB3Periph, FunctionalState NewState);
void RCC_APB1PeriphClockLPModeCmd(uint32_t RCC_APB1Periph, FunctionalState NewState);
void RCC_APB2PeriphClockLPModeCmd(uint32_t RCC_APB2Periph, FunctionalState NewState);
你去仔細的分析:
void RCC_AHB1PeriphClockLPModeCmd(uint32_t RCC_AHB1Periph, FunctionalState NewState);
RCC _ AHB1 PeriphClock LP Mode cmd //RCC_AHB1總線上 _外圍時鐘_LP(PLLP)_模式的指令。
說的很清楚,使用的是pllp的時鐘
其實:外圍時鐘,何為外圍,在STM32的學習中,我一直以為他是一個晶片,一個黑盒子,其實不然,他也是由其他的東西組成: 核心CPU ,外圍的:DMA 、ADC、DAC、UART、USART 、GPIO 、TIM等等都屬于外圍裝置,這玩意又叫做SOC 片上內建系統。
最經典的應該是 stc51單片機了。他沒有內建ADC 、 DAC、DMA 等,仔細想想可以想明白的。
時鐘使能相關函數包括外設設定使能和時鐘源使能兩類。
//第一類是: 外設設定使能函數:
void RCC_AHB1PeriphClockLPModeCmd(uint32_t RCC_AHB1Periph, FunctionalState NewState);
void RCC_AHB2PeriphClockLPModeCmd(uint32_t RCC_AHB2Periph, FunctionalState NewState);
void RCC_AHB3PeriphClockLPModeCmd(uint32_t RCC_AHB3Periph, FunctionalState NewState);
void RCC_APB1PeriphClockLPModeCmd(uint32_t RCC_APB1Periph, FunctionalState NewState);
void RCC_APB2PeriphClockLPModeCmd(uint32_t RCC_APB2Periph, FunctionalState NewState);
這五個函數,分别用來使能5個總線下面挂載的外設時鐘,AHB1 總線, AHB2 總線, AHB3 總線, APB1 總線以及 APB2 總線。要使能某個外設,調用對應的總線外設時鐘使能函數即可。
具體的外設怎麼挂載???看庫函數即可!!!
這個裡面有他 挂載的所有的外設。
還有一類是時鐘源使能函數,
void RCC_HSICmd(FunctionalState NewState);
void RCC_LSICmd(FunctionalState NewState);
void RCC_PLLCmd(FunctionalState NewState);
void RCC_PLLI2SCmd(FunctionalState NewState);
void RCC_PLLSAICmd(FunctionalState NewState);
void RCC_RTCCLKCmd(FunctionalState NewState);
明白一個道理,他跑起來就是168M,系統時鐘,在系統的檔案中已經配置好了。之後到每個外圍的頻率也已經是确定了的。在你不再進行幹預的情況下:
AHB最快是:168M
APB2(高速總線)最快是: 84M
APB1 (低速總線) 最快是:48M