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

STM32F4时钟怎么配置

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

    [LV.1]初来乍到

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

    EDA365欢迎您登录!

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

    x

    6 d/ J; ^5 ?  ]. ]
    # e6 e* Y/ i& ], [( @, f在 STM32F4 标准固件库里,时钟源的选择以及时钟使能等函数都是在RCC相关固件库文件stm32f4xx_rcc.h 和 stm32f4xx_rcc.c 中声明和定义的。大家打开 stm32f4xx_rcc.h 文件可以看到文件开头有很多宏定义标识符,然后是一系列时钟配置和时钟使能函数申明。这些函数大致可以归结为三类,一类是外设时钟使能函数,一类是时钟源和分频因子配置函数,还有一类是外设复位函数。当然还有几个获取时钟源配置的函数。下面我们以几种常见的操作来简要介绍一下这些库函数的使用。: _+ ?' v  B" A/ V5 K/ z7 J7 D
    0 g+ d, c4 f% @% d* e$ t  _/ Q
    首先是时钟使能函数。时钟使能相关函数包括外设设置使能和时钟源使能两类。首先我们来看看外设时钟使能相关的函数:5 o) c; L! `# s' i

    * o9 E2 p- b( c% V  w3 [& }void   RCC_AHB1PeriphClockCmd(uint32_t RCC_AHB1Periph, FunctionalState NewState);
    8 W- W5 L; H: W' F. y, ~3 E0 D
    " R9 X3 _( \5 [% d5 K- H: ]void   RCC_AHB2PeriphClockCmd(uint32_t RCC_AHB2Periph, FunctionalState NewState);9 P! x( N  I/ D9 h, i
    ; ^) U, O# ?# o. V# s$ T' S: a7 |
    void   RCC_AHB3PeriphClockCmd(uint32_t RCC_AHB3Periph, FunctionalState NewState);
    $ f. V1 }2 I! C% [, Q4 F& n
    . e3 v" o% D2 M3 G, tvoid   RCC_APB1PeriphClockCmd(uint32_t RCC_APB1Periph, FunctionalState NewState);: P8 ~; t( l2 U0 b* J1 W. w* a0 f0 E
    , `1 x6 u: Y+ U9 M0 ~# T; B8 J- Q
    void   RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState NewState);
    3 A( ^) }+ \7 M% V3 f: M
    : z* s" s0 ?! ]( a$ t- J* J这里主要有 5 个外设时钟使能函数。5 个函数分别用来使能 5 个总线下面挂载的外设时钟,这些总线分别为:AHB1总线,AHB2总线,AHB3总线,APB1总线以及APB2总线。要使能某个外设,调用对应的总线外设时钟使能函数即可。! Q) T0 u9 J' s3 ?" W4 c8 F
    . ~( O. T- V; s2 L2 ^* K
      这里我们要特别说明一下,STM32F4 的外设在使用之前,必须对时钟进行使能,如果没有使能时钟,那么外设是无法正常工作的。对于哪个外设是挂载在哪个总线之下,虽然我们也可以查手册查询到,但是这里如果大家使用的是库函数的话,实际上是没有必要去查询手册的,这里我们给大家介绍一个小技巧。
    8 H* M- `4 p+ W+ d4 Q! \. w5 r( E+ Z$ q# t; J# ?% f  N5 a
      比如我们要使能GPIOA,我们只需要在stm32f4xx_rcc.h 头文件里面搜索GPIOA,就可以搜索到对应的时钟使能函数的第一个入口参数为 RCC_AHB1Periph_GPIOA,从这个宏定义标识符一眼就可以看出,GPIOA 是挂载在 AHB1 下面。同理,对于串口 1 我们可以搜索 USART1,找到标识符为RCC_APB2Periph_USART1,那么很容易知道串口1是挂载在APB2之下。这个知识在我们后面的“4.7 快速组织代码技巧”小节也有讲解,这里顺带提一下。# [; E8 [0 l  Y* }! u/ \# w

    / j* g7 u) o) X8 e" ]5 a  如果我们要使能 GPIOA,那么我们可以在头文件stm32f4xx_rcc.h 里面查看到宏定义标识符RCC_AHB1Periph_GPIOA,顾名思义 GPIOA 是挂载在 AHB1 总线之下,所以,我们调用AHB1总线下外设时钟使能函数RCC_AHB1PeriphClockCmd 即可。具体调用方式入如下:
    . ]% R* Y0 M+ h* E+ l, K
    # G4 A" M0 \0 aRCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);//使能 GPIOA时钟% D9 S& Y) l/ ]# `" ~$ X

    2 i1 g) k) o2 P2 ]+ Z& z8 n同理,如果我们要使能串口1 的时钟,那么我们调用的函数为:
    4 c/ ^0 R( Y9 X5 S/ ?6 ]7 [/ i9 F# v% T% s
    void   RCC_AHB2PeriphClockCmd(uint32_t RCC_AHB1Periph, FunctionalState NewState);
    . {: x/ m4 \2 q) \- `- k# r6 X. j# i, G" ~, r* t
    具体的调用方法是:
    " n% E" m9 @) a7 T/ u+ X/ I) K4 b; h$ m
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
    6 t6 L% B9 y# B% l0 x
    % s1 V1 F$ q" L7 S7 f! @还有一类时钟使能函数是时钟源使能函数,前面我们已经讲解过 STM32F4 有 5 大类时钟源。这里我们列出来几种重要的时钟源使能函数:
    5 e' M- E6 E6 B& R
    # U( l2 _$ x2 s         void   RCC_HSICmd(FunctionalState NewState);
    0 r, m. g$ O5 H- G$ y
    ) s* N& d0 v6 z3 T% B2 Qvoid   RCC_LSICmd(FunctionalState NewState);
    9 y; i) q, |+ \
    . z3 P3 T8 \5 W% s" h# wvoid   RCC_PLLCmd(FunctionalState NewState);1 A6 ^* c* J* D3 b1 a
    & o4 @: v' i8 A/ Y
    void   RCC_PLLI2SCmd(FunctionalState NewState);
    # w& n. g9 P: ?4 u& i5 s, [: @* [/ F: L9 H  C' c2 Q
    void   RCC_PLLSAICmd(FunctionalState NewState);% `  J+ W# {- f  _* E) R

    ) z9 p3 H! b* _) d4 uvoid   RCC_RTCCLKCmd(FunctionalState NewState);' P2 i& R% w7 l( M: J0 g, t+ w6 K
    " L3 W6 C) A7 }9 o, g
    这些函数是用来使能相应的时钟源。比如我们要使能PLL时钟,那么调用的函数为:2 Z' h9 h' V! S& i

    7 L$ \5 B0 v7 [" ^7 S0 q  t7 a  m( Zvoid   RCC_PLLCmd(FunctionalState NewState);
    ! v% \9 B8 `  C3 {, @4 T; n7 F: a$ T' B5 p" z/ b0 V3 n
    具体调用方法如下:
    ! r7 K9 ?" a" {8 P8 G- T2 t% V! I" w* p  Z
             RCC_PLLCmd(ENABLE);
    / E1 {( P; }# M" L5 B1 [2 e" m6 c9 e! L: r5 ?
    我们要使能相应的时钟源,调用对应的函数即可。, l" q, S# q/ f+ q9 X; Z' ?9 |9 {
    , r, `1 G; y; c# p7 |
      接下来我们要讲解的是第二类时钟功能函数:时钟源选择和分频因子配置函数。这些函数是用来选择相应的时钟源以及配置相应的时钟分频系数。比如我们之前讲解过系统时钟SYSCLK,我们可以选择HSI,HSE以及PLL三个中的一个时钟源为系统时钟。那么到底选择哪一个,这是可以配置的。下面我们列举几种时钟源配置函数:6 A" N: p) B9 t# k# r6 B' c/ q

    5 d: O! r' y) Y8 G         void       RCC_LSEConfig(uint8_t RCC_LSE);* X1 Q2 [; N" m- _- Z. ]# O
    7 e- L# @# ^8 w: c3 l, y
    void        RCC_SYSCLKConfig(uint32_t RCC_SYSCLKSource);8 {1 {' b, l# Q, o8 N$ l7 E8 G8 t- ^
    + ~+ T) I# U' r. S2 ~: b' H' N) a
    void        RCC_HCLKConfig(uint32_t RCC_SYSCLK);
    ' z  b, y" R1 V. O' P7 J5 s  V% t1 a. q0 j" |: U) C
    void      RCC_PCLK1Config(uint32_t RCC_HCLK);$ ?( @* r$ K) J& w9 Z
    , y9 |' {# H  \& d
    void      RCC_PCLK2Config(uint32_t RCC_HCLK);
    3 @0 J* R: c  {) S  D5 E0 M, r7 l& e( ]: B& N
    void       RCC_RTCCLKConfig(uint32_t RCC_RTCCLKSource);6 m- Q" v4 `/ o- I( i, G" u

    ; V9 w! e$ V1 ^3 u& [' P& X* kvoid        RCC_PLLConfig(uint32_t RCC_PLLSource, uint32_t PLLM,  8 g: x2 h& `" m. m: c/ K; {! i; ?* r! s
    4 t) f: v8 `& |) C1 w" j, X
    uint32_t PLLN, uint32_t PLLP, uint32_t PLLQ);. t0 t8 C" H$ `4 W( {) \# z
    ) B0 @8 A' {0 \; X- U
    比如我们要设置系统时钟源为HSI,那么我们可以调用系统时钟源配置函数:
      n- w/ {! a, j: w0 d$ ^3 ?8 r4 L& M  V# O) R, L
    void RCC_SYSCLKConfig(uint32_t RCC_SYSCLKSource);
    # P& N) a! R7 W4 N
    5 S5 I4 i2 c$ ?  I具体配置方法如下:
    & y8 X  t6 f* m7 k# c
    8 J7 Q( [- j+ |& _/ t: K! {2 Hvoid RCC_SYSCLKConfig(RCC_SYSCLKSource_HSI);//配置时钟源为HSI1 t) Q7 y# X9 X: l. X9 r2 E

    3 E$ O( V9 e5 }  又如我们要设置APB1 总线时钟为HCLK的 2分频,也就是设置分频因子为2分频,那么 如果我们要使能HSI,那么调用的函数为:, \" T; V3 r* F

    ! t, E: k! E  C! q. B, q+ qvoid    RCC_PCLK1Config(uint32_t RCC_HCLK);
    7 S6 f- w& X* p# A/ N6 A/ G6 H- f$ r  Z, @, |
      具体配置方法如下:
    1 r% e1 D9 A2 a
    % d/ w3 T0 R9 u8 m# ZRCC_PCLK1Config(RCC_HCLK_Div2);
    ) O5 V, ]# [2 q- l5 r& }
    - p) U( I1 C. d* |" Z  接下来我们看看第三类外设复位函数。如下:7 X& {; d3 N( {
    8 K9 C! |& c4 A. ~! {6 Y: F
    void   RCC_AHB1PeriphResetCmd(uint32_t RCC_AHB1Periph, FunctionalState NewState);
    4 Y8 u3 a+ q- m% J( g7 i: w" y$ f, T* P7 U8 C  N! W  u
    void   RCC_AHB2PeriphResetCmd(uint32_t RCC_AHB2Periph, FunctionalState NewState);
    $ g7 z" Z6 _( Y" D2 `4 T4 R0 _: z3 c! m1 x% a7 W' Q+ h1 [
    void   RCC_AHB3PeriphResetCmd(uint32_t RCC_AHB3Periph, FunctionalState NewState);& B- K' y5 r% Q) o  m$ s( \
    6 a5 I& V! W$ k- P: g0 u  Z
    void   RCC_APB1PeriphResetCmd(uint32_t RCC_APB1Periph, FunctionalState NewState);
    , }. y+ g  X9 O( _( J# D9 A) ^5 m* z+ t$ S) B
    void   RCC_APB2PeriphResetCmd(uint32_t RCC_APB2Periph, FunctionalState NewState);
    : q- M' H. G$ o* k$ u' A% p5 S
    % h) \! e+ H. y3 P2 e: h  |8 S  这类函数跟前面讲解的外设时钟函数使用方法基本一致,不同的是一个是用来使能外设时钟,一个是用来复位对应的外设。这里大家在调用函数的时候一定不要混淆。( T3 y2 u3 c3 u$ n

    7 f7 Z. Q6 H! L! X" p  对于这些时钟操作函数,我们就不一一列举出来,大家可以打开RCC对应的文件仔细了解。
    # x! s" a0 p+ e0 p: ~
      K) \! y/ _9 G3 l$ A
    . U. x6 e% Z0 v( T( ~1 L. f, ]* ?- q7 i- q7 q: A  F) O6 h

    ; `9 B" b* t: j* h
    ) A" |. D4 P3 Y5 I
    您需要登录后才可以回帖 登录 | 注册

    本版积分规则

    关闭

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

    EDA365公众号

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

    GMT+8, 2025-7-18 18:27 , Processed in 0.125000 second(s), 27 queries , Gzip On.

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

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

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