|
上次实验,我们学习了 STM32 内部系统滴答定时器,该滴答定时器产生的延时非常精确。在本次实验中,我们将自定义 RCC 系统时钟,通过改变其倍频与分频实现延时时间变化,实现 LED 灯闪烁效果。通过本次实验,你将了解 RCC 系统时钟的使用。本次实验的目标:% m7 _ V& Z( D3 p 1、了解 STM32 的系统构架。 2、了解 STM32 的时钟构架。 3、了解 RCC 时钟的配置步骤。 * t+ E1 y9 x6 Y$ g1 f STM32 的系统构架0 T- W7 w& ~# r) A; t STM32 的时钟比较复杂,它可以选择多种时钟源,也可以选择不一样的时钟频率,而且在系统总线上面,每条系统的时钟选择都是有差异的。所以想要清楚的了解 STM32 的时钟分配,我们先来了解一下 STM32 的系统构架是什么样的。 从图中我们知道,RCC 时钟输出时钟出来,然后经过 AHB 系统总线,分别分配给其他外设时钟,而不一样的外设,是先挂在不一样的桥上的。比如: ADC1、ADC2、 SPI1、GPIO 等都是挂在 APB2 上面,而有些是挂在 APB1 上面,所以,虽然它们都是从 RCC 获取的时钟,但是它们的频率有时候是不一样的。
3 ]. X4 v2 k8 p* b/ l l' P STM32 的时钟树 STM32 单片机上电之后,系统默认是用的时钟是单片机内部的高速晶振时钟,而这个晶振容易受到温度的影响,所以晶振跳动的时候不是有一定的影响,所以一般开发使用的时候都是使用外部晶振,而且单片机刚启动的时候,它的时钟频率是 8MHZ,而 STM32 时钟的最高频率是 72MHZ,所以单片机一般开机之后运行的程序是切换时钟来源,并设置时钟频率。其实在使用库函数的时候,其实在库函数启动文件里面,是帮助我们把时钟频率设置到 72MHZ 了。 : u7 D6 f0 _& F- P4 @+ B# ]+ l. [ 库函数调用系统时钟该成72M #if defined (STM32F10X_LD_VL) || (defined STM32F10X_MD_VL) || (definedSTM32F10X_HD_VL) /* #define SYSCLK_FREQ_HSE HSE_VALUE */ #define SYSCLK_FREQ_24MHz 24000000 #else! w# {- H" O( \+ N. g" C #define SYSCLK_FREQ_72MHz 72000000 然后在下面的程序中,根据这个 SYSCLK_FREQ_72MHz 定义,它默认设置成72MHZ 接下来我们来看一下 RCC 时钟树
; W X$ q+ Y" S& W c* z5 ~ 从时钟树图我们可以看出,STM32 的时钟一共有可以有 4 个晶振源: 1) 内部自带的高速时钟:HIS。单片机启动之后默认使用的时钟来源。. Z, q& i8 x3 C3 A( J6 y, h2 r 2) 外部高速时钟:HSE。大多数时钟时钟的是 8MHZ 的晶振。 3) 外部低速时钟:LSE。主要用来给单片机内部的 RTC 提供时钟。, c# ?- g! z9 x3 z% U. W7 J 4) 内部的低速时钟:LSI。主要用来给单片机内部的 RTC 和看门狗提供时钟。2 e+ ?( m8 N/ B 而 STM32 的系统时钟源,有 3 个时钟来源:! ?: @ D) Z5 G- h7 M 1) 直接来自内部的高速时钟 HIS。 2) 直接来自外部的高速时钟 HSE。# n- d7 z( H+ i/ ~' d 3) 将 HIS 或者 HSE 进行处理,倍频之后的 PLL 时钟。 4 h' c" \0 c% J) |7 O STM32 配置 RCC 时钟的过程8 b& j5 d; n. ?& h' V$ V- r7 s 1) 复位 RCC 时钟。 2) 打开 HSE 外部高速时钟。3 l1 b: o2 C7 n- O. w 3) 检测 HSE 外部高速时钟是否开启成功。+ i' q6 O9 b, {2 `: ~% m( A- E 4) 设置 FLASH 的读写。 5) 设置 AHB 总线的分频,还有 APB1 和 APB2 的分频。注意,AHB 和 APB2 最 大频率是 72MHZ,APB1 的最大频率是才 36MHZ。 6) 设置 HSE 外部高速时钟作为 PLL 时钟的时钟输入 7) 设置 PLL 时钟的倍频的倍数。 8) 打开 PLL 时钟的使能。 9) 等待 PLL 时钟开启成功。7 ?& ?4 S; I2 I v8 n" U 10) 将系统时钟源设置为 PLL 时钟。 11) 等待时钟源切换成功 。6 H+ E* a" I- l, K; @5 {) o ! T! y. h% @9 R5 ` RCC相关库函数介绍 1.RCC_DeInit() 复位函数是将 RCC 时钟复位为内部高速时钟作为输入,让我们能够进行时钟设置操作。2.RCC_HSEConfig() 函数 设置 HSE 外部高速时钟的函数,可以开启、关闭、和旁路 3.RCC_WaitForHSEStartUp() 函数$ Y8 P! ~# H0 S. i3 R5 F W5 q 4 .RCC_HCLKConfig() 函数- H1 A6 _6 ^4 [; o4 M: C 5 .RCC_PCLK2Config()/ h& W0 A/ ?6 ]) t- M 6 .RCC_PCLK1Config() 函数 8 、RCC_PLLCmd() 函数 9 、RCC_GetFlagStatus() 函数 这个函数可以用来获取各种状态标志,以检测设置是否成功。 10 、 RCC_SYSCLKConfig() 函数 11 、 RCC_GetSYSCLKSource() 0 i5 O- s+ f8 D+ x, y RCC 时钟设置函数8 n( b- x0 |: X3 g void RCC_HSE_Configuration() //自定义系统时间(可以修改时钟) {* e9 p; Q- l% X# _# D2 F RCC_DeInit(); //将外设 RCC 寄存器重设为缺省值5 z" |0 k5 U. w4 v, ?# R RCC_HSEConfig(RCC_HSE_ON);//设置外部高速晶振(HSE)% p3 o6 ^ @0 c9 U e7 Y! E/ c if(RCC_WaitForHSEStartUp()==SUCCESS) //等待 HSE 起振9 s! [( |* W6 B8 `# I {6 @$ R+ \: U6 T" L$ M/ y# K& s RCC_HCLKConfig(RCC_SYSCLK_Div1);//设置 AHB 时钟(HCLK) RCC_PCLK1Config(RCC_HCLK_Div2);//设置低速 AHB 时钟(PCLK1); r+ E I+ Z% m6 S2 w" N RCC_PCLK2Config(RCC_HCLK_Div1);//设置高速 AHB 时钟(PCLK2) RCC_PLLConfig(RCC_PLLSource_HSE_Div2,RCC_PLLMul_9);//设置 PLL 时钟源及倍频系' j9 [+ @2 T" N2 T0 o1 R 数, _( ?1 x" B" s4 _8 |/ H RCC_PLLCmd(ENABLE); //使能或者失能 PLL% V. u* @+ ^1 c/ y while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY)==RESET);//检查指定的 RCC 标志位设置: m6 u) ~9 _3 [' }7 `( q+ s) | 与否,PLL 就绪 RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);//设置系统时钟(SYSCLK)# h3 X5 f8 s: v5 j while(RCC_GetSYSCLKSource()!=0x08);//返回用作系统时钟的时钟源,0x08:PLL 作为 系统时钟) ]: r1 D- X/ C+ }: L4 S } } 这个函数的作用是:设置单片机的时钟来源为 HSE 外部高速时钟,并根据输入频率参数设置相应的频率。 要注意的是设置的输入频率参数一定要是 8 的倍数,并且是从 4 倍到 9 倍的频率数值。* ?7 _8 x: T' b$ ?4 f int main() { led_Init(); //LED 端口初始化0 |* Q6 q5 O" a ?4 _ RCC_HSE_Configuration();// 自定义系统时间,可修改分频 while(1) { 9 s" O3 ~( q# e4 x5 M/ x# F# ` GPIO_SetBits(GPIOB,LED);% ]. d' h& E% D+ h1 l delay_ms(500);//精确延时为 0.5s A6 c0 ^' W0 n, Z7 f GPIO_ResetBits(GPIOB,LED);% h# Q) v$ l Z$ t: F/ W- ^* b delay_ms(500);//精确延时为 0.5s" [( E) a. [( A0 y# Z0 A0 f } } M/ ~0 B: R4 o$ O$ {" @ 这次的系统实验就到这里了。 ' B, b2 ]; ^) P/ v |
消灭0回复 |
微信公众号
手机版