关于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