你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

STM32----系统时钟实验

[复制链接]
feixiang20 发布时间:2018-1-15 20:47
上次实验,我们学习了 STM32 内部系统滴答定时器,该滴答定时器产生的延时非常精确。在本次实验中,我们将自定义 RCC 系统时钟,通过改变其倍频与分频实现延时时间变化,实现 LED 灯闪烁效果。通过本次实验,你将了解 RCC 系统时钟的使用。本次实验的目标:
: R& s& T. u& C7 |1、了解 STM32 的系统构架。" n3 W5 y5 u' }* p9 t$ z& h
2、了解 STM32 的时钟构架。0 t& T0 M3 O. ^) S% Q( h+ P% [
3、了解 RCC 时钟的配置步骤。
6 k! x5 Y4 A; n4 V8 M/ Y' N" [5 m2 l1 R# ]1 K
STM32  的系统构架! f! ]+ T; c& D1 A9 M, J+ s
STM32 的时钟比较复杂,它可以选择多种时钟源,也可以选择不一样的时钟频率,而且在系统总线上面,每条系统的时钟选择都是有差异的。所以想要清楚的了解 STM32 的时钟分配,我们先来了解一下 STM32 的系统构架是什么样的。
0 Z* g7 C, k7 Y5 |7 w0 P) y, v2 A: K0 C; w9 n& |6 I3 L
从图中我们知道,RCC 时钟输出时钟出来,然后经过 AHB 系统总线,分别分配给其他外设时钟,而不一样的外设,是先挂在不一样的桥上的。比如: ADC1、ADC2、 SPI1、GPIO 等都是挂在 APB2 上面,而有些是挂在 APB1 上面,所以,虽然它们都是从 RCC 获取的时钟,但是它们的频率有时候是不一样的。+ a* Z/ p; q; Y; A
) C) f9 x0 y- a" U+ d
1.jpg
8 d) w1 q) W7 h3 K1 y! w4 Q! N+ N& A8 t7 g+ f4 R" {
STM32  的时钟树
! Z: ~7 l7 K& H* e/ Q+ {' y2 hSTM32 单片机上电之后,系统默认是用的时钟是单片机内部的高速晶振时钟,而这个晶振容易受到温度的影响,所以晶振跳动的时候不是有一定的影响,所以一般开发使用的时候都是使用外部晶振,而且单片机刚启动的时候,它的时钟频率是 8MHZ,而 STM32 时钟的最高频率是 72MHZ,所以单片机一般开机之后运行的程序是切换时钟来源,并设置时钟频率。其实在使用库函数的时候,其实在库函数启动文件里面,是帮助我们把时钟频率设置到 72MHZ 了。
: ^! n; G. d* [; a$ u
+ K+ f  Y8 ~/ q' q( p$ t9 k0 k" P库函数调用系统时钟该成72M' G- Q- F" T* p+ G8 @
#if defined (STM32F10X_LD_VL) || (defined STM32F10X_MD_VL) || (definedSTM32F10X_HD_VL)
2 b2 v/ a3 ^3 x7 a. i- {& F$ o/* #define SYSCLK_FREQ_HSE HSE_VALUE */
0 \* [& \$ y* q# {, j+ j7 O#define SYSCLK_FREQ_24MHz 24000000
1 S2 b8 I1 E0 p$ G) r#else
( _2 a3 p# A# X0 H/ D# _4 b#define SYSCLK_FREQ_72MHz 72000000
5 h, c3 g- o( e8 V4 K然后在下面的程序中,根据这个 SYSCLK_FREQ_72MHz 定义,它默认设置成72MHZ
% p6 r0 P) S! z: i3 N4 R7 q
( Y) B' C) V; R5 Y/ n* M# _" j接下来我们来看一下 RCC 时钟树
, M1 A& r$ Q, y( P6 _2 D  d" c
; D1 b  I& Z+ @2 c3 J 2.jpg
& n1 C1 g3 [0 |$ s. G# ?# F: L  d
从时钟树图我们可以看出,STM32 的时钟一共有可以有 4 个晶振源:
- q; b' ]1 U! Z# [3 g+ ~4 ^# N5 V1) 内部自带的高速时钟:HIS。单片机启动之后默认使用的时钟来源。- o' R7 T+ y2 R
2) 外部高速时钟:HSE。大多数时钟时钟的是 8MHZ 的晶振。
# V* X6 a  S3 ~2 H: J* j2 x! |# R7 D3) 外部低速时钟:LSE。主要用来给单片机内部的 RTC 提供时钟。
' ]8 `$ @- y) m$ v2 V4) 内部的低速时钟:LSI。主要用来给单片机内部的 RTC 和看门狗提供时钟。
7 \0 J9 k+ y! E: j; O而 STM32 的系统时钟源,有 3 个时钟来源:
9 S+ l5 G( X9 q! h8 t* v1) 直接来自内部的高速时钟 HIS。+ q- n1 Y* u( h0 C: G
2) 直接来自外部的高速时钟 HSE。
, I; w, s0 j: {5 b3) 将 HIS 或者 HSE 进行处理,倍频之后的 PLL 时钟。: r+ N6 Y2 Q" i( ], d( Z9 n
6 E: H3 B& w% E6 g) l
STM32  配置 RCC  时钟的过程
4 y5 W6 z' s  `. f7 O1) 复位 RCC 时钟。4 p/ l6 V- E7 O7 d
2) 打开 HSE 外部高速时钟。
0 d- f! o) T9 y$ U+ R5 }3) 检测 HSE 外部高速时钟是否开启成功。
- M# M" r& ?% _3 }: k4) 设置 FLASH 的读写。 9 [$ M5 I* R; f' g8 a7 C( b7 G
5) 设置 AHB 总线的分频,还有 APB1 和 APB2 的分频。注意,AHB 和 APB2 最
- x/ y3 {0 L# U& J0 z% E8 t大频率是 72MHZ,APB1 的最大频率是才 36MHZ。4 A0 D* v$ u2 b5 Z/ V% |" G
6) 设置 HSE 外部高速时钟作为 PLL 时钟的时钟输入 " C- u6 q8 \2 i; W" J  G* N
7) 设置 PLL 时钟的倍频的倍数。+ y4 ]! i* h3 t1 j4 e, h/ q
8) 打开 PLL 时钟的使能。
# }( W, w# p5 `9) 等待 PLL 时钟开启成功。+ y8 G( @# I8 [7 Q. S9 ]
10) 将系统时钟源设置为 PLL 时钟。6 N4 e2 [) {" V0 C7 p4 s
11) 等待时钟源切换成功 。7 X  a! @! B& W$ _$ f! I" P
* F1 m% i+ D  e
RCC相关库函数介绍: Y9 z: @! t! B1 t% n
1.RCC_DeInit() 复位函数是将 RCC 时钟复位为内部高速时钟作为输入,让我们能够进行时钟设置操作。2.RCC_HSEConfig() 函数  设置 HSE 外部高速时钟的函数,可以开启、关闭、和旁路
3 o) E/ B# F8 {. D1 z2 \3.RCC_WaitForHSEStartUp() 函数" i: j! \# d3 V% Y* W0 S' b
4 .RCC_HCLKConfig() 函数; W9 j: f6 |/ S# a
5 .RCC_PCLK2Config()8 Q" F5 S: P% r7 Q3 \( u/ y- i% G
6 .RCC_PCLK1Config() 函数9 C3 a! T2 N* h/ W
8 、RCC_PLLCmd() 函数. q+ P" k& L6 b) `$ \$ ?
9 、RCC_GetFlagStatus() 函数  这个函数可以用来获取各种状态标志,以检测设置是否成功。- b' A5 q* \2 Q7 z7 K
10 、 RCC_SYSCLKConfig() 函数
' Y7 }* B; Q5 P% S11 、 RCC_GetSYSCLKSource()
5 M4 |  s: \& ?, J- ~& x
/ b8 V# `6 Z2 q! F5 oRCC  时钟设置函数/ N4 X8 J' Z/ M+ t
void RCC_HSE_Configuration() //自定义系统时间(可以修改时钟)
; K' x/ _0 h2 _2 g2 |{) Z2 N1 O4 J7 Y0 e1 O
RCC_DeInit(); //将外设 RCC 寄存器重设为缺省值( z; s: w' ]2 Y5 Y  X! T, p6 P
RCC_HSEConfig(RCC_HSE_ON);//设置外部高速晶振(HSE)6 i8 f+ m+ g5 W
if(RCC_WaitForHSEStartUp()==SUCCESS) //等待 HSE 起振" F9 b1 d) ~3 U( D+ i5 [& l8 ^( d
{
6 _, d9 P! U+ C( q* y, gRCC_HCLKConfig(RCC_SYSCLK_Div1);//设置 AHB 时钟(HCLK)
5 X  @9 r2 F8 R  V) b: PRCC_PCLK1Config(RCC_HCLK_Div2);//设置低速 AHB 时钟(PCLK1)1 b& N' J" E, I0 {! s$ `) f& f& t# U
RCC_PCLK2Config(RCC_HCLK_Div1);//设置高速 AHB 时钟(PCLK2)1 @% c5 q( l% g) T
RCC_PLLConfig(RCC_PLLSource_HSE_Div2,RCC_PLLMul_9);//设置 PLL 时钟源及倍频系
1 N& c0 l6 l/ [1 f
" H+ c9 |* u- X' ?! pRCC_PLLCmd(ENABLE); //使能或者失能 PLL0 [/ i( A6 |. h) |! R6 R
while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY)==RESET);//检查指定的 RCC 标志位设置
1 n0 ]. g- [2 c5 Z/ _# A9 a; y! t与否,PLL 就绪
! u4 q+ [- M. v  U" jRCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);//设置系统时钟(SYSCLK)
4 |" C1 D/ B& J/ t  @( z1 E! ?while(RCC_GetSYSCLKSource()!=0x08);//返回用作系统时钟的时钟源,0x08:PLL 作为3 a5 x( H6 h9 _7 v7 ~! F9 J
系统时钟4 Y; m  p4 y' ~; l/ i
}/ ^! ]; b# ]4 Y" B, f) ]7 I
}& V6 I  Q' V4 |# C

8 M; V' G# y% q& }这个函数的作用是:设置单片机的时钟来源为 HSE 外部高速时钟,并根据输入频率参数设置相应的频率。 要注意的是设置的输入频率参数一定要是 8 的倍数,并且是从 4 倍到 9 倍的频率数值。  l5 }+ _  L7 K8 W" u4 f

) F7 g& L, b' H* a, L$ |" Nint main()
  H8 h: {2 e$ r; [, l8 V{ . ~! C( I$ ~" ]% ?/ p6 I
led_Init();  //LED 端口初始化0 h/ b* P2 D7 z
RCC_HSE_Configuration();// 自定义系统时间,可修改分频3 B6 `! W" |1 q1 h$ [. f3 i' y+ t# j
while(1)
( C9 G9 B4 G2 I$ @* N2 P4 ^{
) t& I1 x* X0 n( B0 qGPIO_SetBits(GPIOB,LED);
* K  A3 X, b# [9 odelay_ms(500);//精确延时为 0.5s
2 c* u& [* O& a! \& A( QGPIO_ResetBits(GPIOB,LED);
9 q1 ]3 V4 x, P  y8 j! Xdelay_ms(500);//精确延时为 0.5s0 M) v" w; k% K7 N; @. S+ J" s
}
( F. @* @8 X9 Q3 Q}" i6 L2 R* J. B0 n& S' k; H
这次的系统实验就到这里了。1 T# d$ [1 m5 B+ o! u+ ?+ |

( f4 c7 Z. E/ o
收藏 评论1 发布时间:2018-1-15 20:47

举报

1个回答
anywill 回答时间:2018-1-15 21:45:16
消灭0回复

所属标签

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版