找回密码
 注册
关于网站域名变更的通知
查看: 70|回复: 0
打印 上一主题 下一主题

STM32F4时钟怎么配置

[复制链接]
  • TA的每日心情
    开心
    2023-5-15 15:14
  • 签到天数: 1 天

    [LV.1]初来乍到

    跳转到指定楼层
    1#
     楼主| 发表于 2024-11-4 14:59 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式

    EDA365欢迎您登录!

    您需要 登录 才可以下载或查看,没有帐号?注册

    x

    . r. P1 b& x; R! {# J) M! Q( y! h6 g  |, Q
    在 STM32F4 标准固件库里,时钟源的选择以及时钟使能等函数都是在RCC相关固件库文件stm32f4xx_rcc.h 和 stm32f4xx_rcc.c 中声明和定义的。大家打开 stm32f4xx_rcc.h 文件可以看到文件开头有很多宏定义标识符,然后是一系列时钟配置和时钟使能函数申明。这些函数大致可以归结为三类,一类是外设时钟使能函数,一类是时钟源和分频因子配置函数,还有一类是外设复位函数。当然还有几个获取时钟源配置的函数。下面我们以几种常见的操作来简要介绍一下这些库函数的使用。
    ' d0 W! J- |0 u( y- M- n
    ( [- |, {. e/ C& a首先是时钟使能函数。时钟使能相关函数包括外设设置使能和时钟源使能两类。首先我们来看看外设时钟使能相关的函数:
    ) ]9 M; ^. h7 p# c8 f, G, \; D$ }9 m
    6 f: [- S+ c+ x) \) @, jvoid   RCC_AHB1PeriphClockCmd(uint32_t RCC_AHB1Periph, FunctionalState NewState);& b+ P" u6 ~' |; i! j+ E
    ( w* ^) k( B7 _' @
    void   RCC_AHB2PeriphClockCmd(uint32_t RCC_AHB2Periph, FunctionalState NewState);$ h' s5 H/ ?7 ]* O
    . @/ D: a; ~9 ?$ o
    void   RCC_AHB3PeriphClockCmd(uint32_t RCC_AHB3Periph, FunctionalState NewState);3 `+ A0 P* o  g
    ' {3 T) {1 X: w. W
    void   RCC_APB1PeriphClockCmd(uint32_t RCC_APB1Periph, FunctionalState NewState);4 f! B6 Z  ^! |

    8 r$ D& u: K! c; D# f1 Bvoid   RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState NewState);
    9 j# h9 S) Q. Y7 s$ J% m. {9 Q3 W9 a6 f' m6 X+ H! B
    这里主要有 5 个外设时钟使能函数。5 个函数分别用来使能 5 个总线下面挂载的外设时钟,这些总线分别为:AHB1总线,AHB2总线,AHB3总线,APB1总线以及APB2总线。要使能某个外设,调用对应的总线外设时钟使能函数即可。
    + `1 G( m% i* A. D  M1 Q) k. G
    ) V7 e8 p1 y% {/ M& S3 }  这里我们要特别说明一下,STM32F4 的外设在使用之前,必须对时钟进行使能,如果没有使能时钟,那么外设是无法正常工作的。对于哪个外设是挂载在哪个总线之下,虽然我们也可以查手册查询到,但是这里如果大家使用的是库函数的话,实际上是没有必要去查询手册的,这里我们给大家介绍一个小技巧。6 o9 u# e% ~$ }9 u

    3 o2 f. U" X1 A7 Q, b  比如我们要使能GPIOA,我们只需要在stm32f4xx_rcc.h 头文件里面搜索GPIOA,就可以搜索到对应的时钟使能函数的第一个入口参数为 RCC_AHB1Periph_GPIOA,从这个宏定义标识符一眼就可以看出,GPIOA 是挂载在 AHB1 下面。同理,对于串口 1 我们可以搜索 USART1,找到标识符为RCC_APB2Periph_USART1,那么很容易知道串口1是挂载在APB2之下。这个知识在我们后面的“4.7 快速组织代码技巧”小节也有讲解,这里顺带提一下。
    - a. P. w1 C, o+ v+ c
    0 \( J1 e8 `: l2 G* C; u0 O4 G  如果我们要使能 GPIOA,那么我们可以在头文件stm32f4xx_rcc.h 里面查看到宏定义标识符RCC_AHB1Periph_GPIOA,顾名思义 GPIOA 是挂载在 AHB1 总线之下,所以,我们调用AHB1总线下外设时钟使能函数RCC_AHB1PeriphClockCmd 即可。具体调用方式入如下:. m/ e3 R) Y7 |% v+ R) Y  E- G/ @

    ; s8 D: \. f" I! c; Y( s7 d4 IRCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);//使能 GPIOA时钟( Y2 \& \6 @; v# d- c! ^- U

    . E8 d1 q1 x+ o6 k3 R同理,如果我们要使能串口1 的时钟,那么我们调用的函数为:
    , c. v, R' I, n  d
    # M0 _, Z4 T+ H2 P: Xvoid   RCC_AHB2PeriphClockCmd(uint32_t RCC_AHB1Periph, FunctionalState NewState);+ m* w+ c# m: c" ^4 A4 w
    ! K5 m- `! ^, Z3 }; }
    具体的调用方法是:# r' V) _  c% P# V$ N. ^

    . l5 l" B' m5 H/ o: u1 XRCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
    8 L; G) ]0 c- W; N1 F0 o) A" o5 T, n& }5 @5 X. F* V# Y. e
    还有一类时钟使能函数是时钟源使能函数,前面我们已经讲解过 STM32F4 有 5 大类时钟源。这里我们列出来几种重要的时钟源使能函数:
    ! Y8 K3 w, W9 H6 O, d$ }$ h! f
    - g: s% K$ ]# [  t: d3 D         void   RCC_HSICmd(FunctionalState NewState);
    : Y/ ]  A( z5 a7 T3 o9 h) Q
    ! l. d: T( o! X- a0 Evoid   RCC_LSICmd(FunctionalState NewState);/ h! V' x  R$ V% F5 a9 M( _' D: k# n8 x
    3 f& I$ D& Y7 T; Z; ]' ]. @1 u; h
    void   RCC_PLLCmd(FunctionalState NewState);
    ) j& h! s9 \* j" b" l, j3 Z2 N# M
    * d, b* a  V1 `! a: C+ R1 ]void   RCC_PLLI2SCmd(FunctionalState NewState);4 P% s: G& }' u
    6 V: j$ X3 l% S
    void   RCC_PLLSAICmd(FunctionalState NewState);9 C% \" i( S8 g

    4 O8 n! l% l8 q6 V/ Rvoid   RCC_RTCCLKCmd(FunctionalState NewState);  X$ a- I2 z, [

    & b9 Y* d3 d/ x5 s; }这些函数是用来使能相应的时钟源。比如我们要使能PLL时钟,那么调用的函数为:$ |0 U) h8 H. v

    ! c8 I& u$ p: t$ `void   RCC_PLLCmd(FunctionalState NewState);
    7 n3 e6 G8 @+ N) {. L8 u  U7 f5 i' k2 e
    具体调用方法如下:
    5 e9 Q8 O% u* Y" J7 b5 ?# _
    ' ?2 D% J7 o' k1 |. L. t5 R* f; P         RCC_PLLCmd(ENABLE);
    % z" U5 W6 O; t6 J$ L) R, E# q8 t+ S8 ~0 n7 u- [3 L
    我们要使能相应的时钟源,调用对应的函数即可。
    9 W" q# ?2 o. m. {/ ^* ~: B& B2 X+ Z1 Q& D3 t. m
      接下来我们要讲解的是第二类时钟功能函数:时钟源选择和分频因子配置函数。这些函数是用来选择相应的时钟源以及配置相应的时钟分频系数。比如我们之前讲解过系统时钟SYSCLK,我们可以选择HSI,HSE以及PLL三个中的一个时钟源为系统时钟。那么到底选择哪一个,这是可以配置的。下面我们列举几种时钟源配置函数:4 m8 S3 z0 K4 K0 D* w

    1 Q! B6 P8 R3 U* l4 ?' ]; L; N         void       RCC_LSEConfig(uint8_t RCC_LSE);
    2 h1 |: B' ?: h, \3 k
    * e, _4 d/ f0 D) z1 O2 Dvoid        RCC_SYSCLKConfig(uint32_t RCC_SYSCLKSource);9 w+ O# J/ T+ q7 w

    ; ^8 n8 i. `$ k1 f/ M/ ~/ L4 |& ovoid        RCC_HCLKConfig(uint32_t RCC_SYSCLK);
    9 h) c: s- ?) x. h, `: w. v
    ( p; z# h% C, \1 b( J2 t. ~! P2 Xvoid      RCC_PCLK1Config(uint32_t RCC_HCLK);: l. k9 ~( }( u* Y% g
    7 S3 i1 {  D& x! |9 ~7 t. _
    void      RCC_PCLK2Config(uint32_t RCC_HCLK);
    / V2 K' x% i( L, R9 e+ u8 T% s! ^* I( v7 x. i
    void       RCC_RTCCLKConfig(uint32_t RCC_RTCCLKSource);
    8 L+ m0 w& ?/ W6 A6 C
    # h1 D0 G6 b: q+ b' Y+ L  M* I9 q* ovoid        RCC_PLLConfig(uint32_t RCC_PLLSource, uint32_t PLLM,  
    2 J( \( p; V- \7 @: i9 u5 v, [2 v  c
    uint32_t PLLN, uint32_t PLLP, uint32_t PLLQ);$ k$ q. o) I  G
    . g( X! U  X. Y% t: p$ h; h
    比如我们要设置系统时钟源为HSI,那么我们可以调用系统时钟源配置函数:
    0 m1 G) e  e9 J+ G2 t
    $ J3 s6 c6 ^, \+ q, kvoid RCC_SYSCLKConfig(uint32_t RCC_SYSCLKSource);/ [  g6 Y% S7 |9 n
    5 u+ e0 P7 |. u& n7 h: K
    具体配置方法如下:) ^* O: h* L- f
      o) G1 D) v9 I# L& s% B8 P9 A6 O
    void RCC_SYSCLKConfig(RCC_SYSCLKSource_HSI);//配置时钟源为HSI
    ) i# J1 e4 v, _5 z6 V4 z4 @# ]. P7 ^$ h, l+ S8 }: L4 Q/ j8 \& [
      又如我们要设置APB1 总线时钟为HCLK的 2分频,也就是设置分频因子为2分频,那么 如果我们要使能HSI,那么调用的函数为:  d- h6 G3 d4 X; u2 Z' D; L

    6 h' f- T$ i: c4 I. n# M" }5 _1 }void    RCC_PCLK1Config(uint32_t RCC_HCLK);
    " U! Q1 j- `2 K) h& ?% ^8 f$ `0 K! F# l+ f% J. l) O" J
      具体配置方法如下:% r6 N  V  W% ]
    . s8 a  R; b( H
    RCC_PCLK1Config(RCC_HCLK_Div2);9 Q' v2 s2 ~# y! l, r: P' G5 D; ]
    9 x9 Z1 H# _( w5 l
      接下来我们看看第三类外设复位函数。如下:+ V0 c+ M+ I. Z+ U* `( r

    1 u! g% i; f$ l# d8 {2 f. f% Qvoid   RCC_AHB1PeriphResetCmd(uint32_t RCC_AHB1Periph, FunctionalState NewState);4 m/ [2 k6 `! a4 j4 v
    4 D3 L. \/ q' V3 j
    void   RCC_AHB2PeriphResetCmd(uint32_t RCC_AHB2Periph, FunctionalState NewState);
    ! `' ~4 U( ]2 P. A9 t
    7 G( H8 l/ `- a" T3 _void   RCC_AHB3PeriphResetCmd(uint32_t RCC_AHB3Periph, FunctionalState NewState);7 y! A9 t( g9 J, C
      T/ L, m; n1 C
    void   RCC_APB1PeriphResetCmd(uint32_t RCC_APB1Periph, FunctionalState NewState);
    3 [4 V1 t# m, D, Q! A. x1 @" D% o
    void   RCC_APB2PeriphResetCmd(uint32_t RCC_APB2Periph, FunctionalState NewState);* G" k: t5 P4 @9 T7 M( V

    & x" l& T$ _! z& A* f- k6 T  这类函数跟前面讲解的外设时钟函数使用方法基本一致,不同的是一个是用来使能外设时钟,一个是用来复位对应的外设。这里大家在调用函数的时候一定不要混淆。
    * z8 e5 a7 E/ [2 N" i6 n
    5 K% \! ]: Y) K' j0 v  对于这些时钟操作函数,我们就不一一列举出来,大家可以打开RCC对应的文件仔细了解。* d+ E2 `" q& E6 F. ~. y5 |
    & x. l5 _- ~; d8 c; P5 A6 G* y
    ! b: ]$ C" ~" Z
    9 r/ A% G$ l) ~! ^5 @; S

    % h, d1 x6 }, U/ u9 _3 M* X7 o' I# |. g
    7 f2 p0 w! A# l2 b2 E  q
    您需要登录后才可以回帖 登录 | 注册

    本版积分规则

    关闭

    推荐内容上一条 /1 下一条

    EDA365公众号

    关于我们|手机版|EDA365电子论坛网 ( 粤ICP备18020198号-1 )

    GMT+8, 2025-9-24 05:19 , Processed in 0.140625 second(s), 28 queries , Gzip On.

    深圳市墨知创新科技有限公司

    地址:深圳市南山区科技生态园2栋A座805 电话:19926409050

    快速回复 返回顶部 返回列表