找回密码
 注册
查看: 46|回复: 0
打印 上一主题 下一主题

STM32F4时钟怎么配置

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

    [LV.1]初来乍到

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

    EDA365欢迎您登录!

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

    x

    ; f* |6 i) h5 O; X: |  q: P( ?& M/ p+ F. s/ N
    在 STM32F4 标准固件库里,时钟源的选择以及时钟使能等函数都是在RCC相关固件库文件stm32f4xx_rcc.h 和 stm32f4xx_rcc.c 中声明和定义的。大家打开 stm32f4xx_rcc.h 文件可以看到文件开头有很多宏定义标识符,然后是一系列时钟配置和时钟使能函数申明。这些函数大致可以归结为三类,一类是外设时钟使能函数,一类是时钟源和分频因子配置函数,还有一类是外设复位函数。当然还有几个获取时钟源配置的函数。下面我们以几种常见的操作来简要介绍一下这些库函数的使用。% J, n# k$ _) Z

    5 q% A: m& V; E8 l- W! b& K; n首先是时钟使能函数。时钟使能相关函数包括外设设置使能和时钟源使能两类。首先我们来看看外设时钟使能相关的函数:
    : |, _# c5 k$ s9 H7 Q
    ! c- N7 e$ O8 q$ |& |void   RCC_AHB1PeriphClockCmd(uint32_t RCC_AHB1Periph, FunctionalState NewState);
    ) g1 _+ S; W8 q8 v9 C4 c9 u# R% K* v6 N# _
    void   RCC_AHB2PeriphClockCmd(uint32_t RCC_AHB2Periph, FunctionalState NewState);
    2 D; w# q6 U5 N3 k. A8 I/ v, }' Y$ i8 O  T6 M, A
    void   RCC_AHB3PeriphClockCmd(uint32_t RCC_AHB3Periph, FunctionalState NewState);* I! o9 Y% b: U8 P+ _  W/ Y
    , d3 q  O2 p5 y* r* ^3 j5 {3 v
    void   RCC_APB1PeriphClockCmd(uint32_t RCC_APB1Periph, FunctionalState NewState);+ v. g* |4 Y# g  N% c7 K

    ; i8 M7 A# I9 }- T% U( l7 ~) P4 @9 ovoid   RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState NewState);
    5 w3 J% h. D9 p$ n2 a% _# L+ ?  B/ {) @7 t2 g9 }) d
    这里主要有 5 个外设时钟使能函数。5 个函数分别用来使能 5 个总线下面挂载的外设时钟,这些总线分别为:AHB1总线,AHB2总线,AHB3总线,APB1总线以及APB2总线。要使能某个外设,调用对应的总线外设时钟使能函数即可。7 Z9 V0 @9 ]' R7 S) P1 R

    5 n- y6 l: M0 T+ d1 e4 }  这里我们要特别说明一下,STM32F4 的外设在使用之前,必须对时钟进行使能,如果没有使能时钟,那么外设是无法正常工作的。对于哪个外设是挂载在哪个总线之下,虽然我们也可以查手册查询到,但是这里如果大家使用的是库函数的话,实际上是没有必要去查询手册的,这里我们给大家介绍一个小技巧。
    & _1 v+ ]5 W6 m0 @1 r5 F
    ; j" g$ U4 N6 [: ?  比如我们要使能GPIOA,我们只需要在stm32f4xx_rcc.h 头文件里面搜索GPIOA,就可以搜索到对应的时钟使能函数的第一个入口参数为 RCC_AHB1Periph_GPIOA,从这个宏定义标识符一眼就可以看出,GPIOA 是挂载在 AHB1 下面。同理,对于串口 1 我们可以搜索 USART1,找到标识符为RCC_APB2Periph_USART1,那么很容易知道串口1是挂载在APB2之下。这个知识在我们后面的“4.7 快速组织代码技巧”小节也有讲解,这里顺带提一下。
    . S  m  Q0 U2 J/ s# C  T; [7 {+ ~6 a, u$ m# {6 b. ?, v' w# Y; M
      如果我们要使能 GPIOA,那么我们可以在头文件stm32f4xx_rcc.h 里面查看到宏定义标识符RCC_AHB1Periph_GPIOA,顾名思义 GPIOA 是挂载在 AHB1 总线之下,所以,我们调用AHB1总线下外设时钟使能函数RCC_AHB1PeriphClockCmd 即可。具体调用方式入如下:
    3 f0 L3 N/ X$ k, n- W* I' P! o" [6 }2 D9 R& |, q$ p. z5 ]
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);//使能 GPIOA时钟# k! H( ^7 p% N' _: `% {

    ! d9 p% S$ o" l5 h* G! d同理,如果我们要使能串口1 的时钟,那么我们调用的函数为:# g# m5 V0 {& i$ W$ g

    6 V7 N# G7 N2 }% Z3 p1 D! R7 @: qvoid   RCC_AHB2PeriphClockCmd(uint32_t RCC_AHB1Periph, FunctionalState NewState);
    * P9 g; K( q5 G* J
    $ E& V4 m5 [, z/ J/ ~具体的调用方法是:
    5 X# k! x7 |7 f! ]5 e1 v* {3 N7 Y& G3 p. \
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
    8 H# v2 z- ^: {1 C4 T" `1 @! j
    / N3 N  ]6 }/ {还有一类时钟使能函数是时钟源使能函数,前面我们已经讲解过 STM32F4 有 5 大类时钟源。这里我们列出来几种重要的时钟源使能函数:- j1 D$ y; H) l, j

    9 X7 F: M- L& ]: H: i  H  |8 O         void   RCC_HSICmd(FunctionalState NewState);
    ' S) i! S" q3 E8 A6 {* O2 ]& d5 p, |( m2 f, M! P  s0 d  h+ N4 t# g& F
    void   RCC_LSICmd(FunctionalState NewState);9 s. D$ z) H% {2 |9 ^$ z

    . l& j5 B6 p: [void   RCC_PLLCmd(FunctionalState NewState);4 R: O: i9 d; M, x2 Q+ X
    ' R# |  r7 L/ X+ A* w& W
    void   RCC_PLLI2SCmd(FunctionalState NewState);
    & j* e7 {9 X0 Q
    * V9 `- Q  F, b; L. hvoid   RCC_PLLSAICmd(FunctionalState NewState);; Q* ?2 R. p" F

    9 q1 G- y1 [5 z$ hvoid   RCC_RTCCLKCmd(FunctionalState NewState);
    # \$ b" E5 a: i8 E5 |9 t0 ~5 c6 f4 z- X. W! E: S
    这些函数是用来使能相应的时钟源。比如我们要使能PLL时钟,那么调用的函数为:
    ; G- s9 S) d' g; H: V7 i8 l" Q3 F% D8 B/ `
    void   RCC_PLLCmd(FunctionalState NewState);! Z4 [4 z* _9 @

    7 b) C, y% h9 O" d  S; n+ @具体调用方法如下:6 C8 M" [" F$ i% A5 C- W1 K+ |7 x

    & U6 ]; e2 C( `" F2 `         RCC_PLLCmd(ENABLE);
    + H# V1 N2 J% c% g2 Y. O) M6 g6 u4 r' F$ O# U" P7 p. [4 i8 S. J
    我们要使能相应的时钟源,调用对应的函数即可。8 a3 n- c4 U3 [+ a* k! E& ~. g

    % e3 @; ?, x4 _$ l  接下来我们要讲解的是第二类时钟功能函数:时钟源选择和分频因子配置函数。这些函数是用来选择相应的时钟源以及配置相应的时钟分频系数。比如我们之前讲解过系统时钟SYSCLK,我们可以选择HSI,HSE以及PLL三个中的一个时钟源为系统时钟。那么到底选择哪一个,这是可以配置的。下面我们列举几种时钟源配置函数:0 W( n" y7 ~8 @* u; q
    ) o+ R; z! Q% u8 l7 r+ e  Y( o
             void       RCC_LSEConfig(uint8_t RCC_LSE);
    ( B  Y7 L9 o* o  `- E2 `9 g, o
    . ~  |9 z4 ?& Ivoid        RCC_SYSCLKConfig(uint32_t RCC_SYSCLKSource);
    5 j7 j! j6 ]1 v# y: H5 Z9 r% {  e
    , D* I5 O8 g6 d" ~; Y- ^void        RCC_HCLKConfig(uint32_t RCC_SYSCLK);; a7 _! d! ?# M7 h4 K

    / W- g- Z( b* O, _void      RCC_PCLK1Config(uint32_t RCC_HCLK);
    ; q' g" A( M5 U1 K4 d- `/ j# g, `; K$ f2 _' h5 d# B- |
    void      RCC_PCLK2Config(uint32_t RCC_HCLK);4 u4 j- u! p+ v& d) {6 g) [
    1 d" ]: r/ R4 C
    void       RCC_RTCCLKConfig(uint32_t RCC_RTCCLKSource);
    " m, p: r/ o2 t: Z' d9 `! L# l2 b4 _# @
    void        RCC_PLLConfig(uint32_t RCC_PLLSource, uint32_t PLLM,  9 k5 b) K7 f! V/ i. e

    * e9 H7 T4 J8 Q+ juint32_t PLLN, uint32_t PLLP, uint32_t PLLQ);/ b9 q. P1 F& I; U7 T4 Q. N5 X

    5 C/ C  l- Z2 O- l( D比如我们要设置系统时钟源为HSI,那么我们可以调用系统时钟源配置函数:3 F! ~# A, r$ a( S7 z6 S2 i

    4 l# t5 f4 H. @% S2 {void RCC_SYSCLKConfig(uint32_t RCC_SYSCLKSource);! Q# o2 Z. W! Q' ?' ~& E# D

    4 q& z+ c- p  f6 i1 N; \: O; f) U具体配置方法如下:2 l+ H# t1 \; W& U$ A' I# {

    / r3 a- Y4 ~8 k$ M8 I' hvoid RCC_SYSCLKConfig(RCC_SYSCLKSource_HSI);//配置时钟源为HSI
    7 @0 M$ ^$ I& C  j+ {( Q# V, a( }8 {5 n' h
      又如我们要设置APB1 总线时钟为HCLK的 2分频,也就是设置分频因子为2分频,那么 如果我们要使能HSI,那么调用的函数为:
    1 g" {: V4 v9 |3 z& W
    5 c* G- r% P( U' }void    RCC_PCLK1Config(uint32_t RCC_HCLK);
    & J, U! J" b! w; }: I8 b5 L- }4 z8 [" _6 U  n; H( A+ y% f
      具体配置方法如下:
    % p; O  a% n' I! ]6 J& s5 k4 v& P" H7 |1 P1 Z4 S
    RCC_PCLK1Config(RCC_HCLK_Div2);9 o0 T. ?1 z  V9 h: }
    ; ?. y" S" H) {0 T6 R0 b+ V
      接下来我们看看第三类外设复位函数。如下:
    + l9 T% Z% ^; A+ h% {: z6 E8 H: t! k% D0 h1 I7 i
    void   RCC_AHB1PeriphResetCmd(uint32_t RCC_AHB1Periph, FunctionalState NewState);
    2 x& i9 w/ Y8 |2 z( a4 @( p6 G3 j. E. @( s. @- S. V' \
    void   RCC_AHB2PeriphResetCmd(uint32_t RCC_AHB2Periph, FunctionalState NewState);
    1 Q  s, d4 o# Z" U- w# j5 ?- H& l
    void   RCC_AHB3PeriphResetCmd(uint32_t RCC_AHB3Periph, FunctionalState NewState);$ m' G/ t) {: V( a' S8 y

    % z) G& g9 B7 z$ Z2 [8 s* ?void   RCC_APB1PeriphResetCmd(uint32_t RCC_APB1Periph, FunctionalState NewState);
    6 N4 J* U/ T- p& |
    0 J: u( y( ^8 a: L/ b8 w5 ovoid   RCC_APB2PeriphResetCmd(uint32_t RCC_APB2Periph, FunctionalState NewState);
    ; S: n2 `) ^; K2 ?0 f/ j" B' E- `5 {* {0 Z. L
      这类函数跟前面讲解的外设时钟函数使用方法基本一致,不同的是一个是用来使能外设时钟,一个是用来复位对应的外设。这里大家在调用函数的时候一定不要混淆。
    6 [- E- x6 A  n3 B$ v$ U3 ]  D" D) X" X
      对于这些时钟操作函数,我们就不一一列举出来,大家可以打开RCC对应的文件仔细了解。
    ) P7 A/ A' y% d7 ~+ L, a
    ; P/ U; W/ h& p( y7 ^7 r
    % P. [) ]" k9 ]& F8 y3 f$ Q1 Y4 u  o' {0 R, a3 r

    - d* z( q; X" b/ A
    6 ^# k' A$ A4 D* _/ F; k  p+ d  T0 U
    您需要登录后才可以回帖 登录 | 注册

    本版积分规则

    关闭

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

    EDA365公众号

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

    GMT+8, 2025-6-1 03:14 , Processed in 0.093750 second(s), 27 queries , Gzip On.

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

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

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