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

【经验分享】stm32之RCC

[复制链接]
STMCU小助手 发布时间:2022-1-22 17:54
 stm32时钟系统的意义:
    1、电源的开关作用,达到低功耗效果;
    2、调节时钟的速度;
对于每个外设,都要设置设置,stm32的时钟系统为了更低功耗;
STM32时钟系统框图分析: 301552013133415.png
) P: D6 \, b; |7 {
: U0 X  z/ L8 ]6 z- i, ]时钟源:
  时钟是STM32的脉搏,是驱动源。使用任何一个外设都必须打开相应的时钟。这样的好处就是,如果不是用一个外设的时候,就把它的时钟关掉,从而可以降低系统的功耗,达到节能,实现低功耗的效果;
  stm32的时钟可以有以下4个时钟源提供:
    1、HSI:高速内部时钟信号stm32单片机内带的时钟(8M频率),缺点是精度较差;
    2、HSE:高速外部时钟信号,精度高  来源:(1)、外部晶振 (2)、HSE用户外部时钟;
    3、LSE:低速外部晶振 32.768khz主要提供一个精准的时钟源,一般作为RTC时钟使用;
    4、LSI:内部低速时钟,提供独立看门狗,也可以给RTC;
  STM32将时钟信号(例如HSE)经过分频或倍频(PLL)后,得到系统时钟,系统时钟经过分频,产生外设所使用的时钟;
RCC设置流程: 
  1、将RCC寄存器重新设置为默认值    RCC_DeInit
  2、打开外部高速时钟晶振HSE      RCC_HSEConfig(RCC_HSE_ON)
  3、等待外部高速时钟晶振工作      HSEStartUpStatus = RCC_WaitForHSEStartUp();
  4、设置AHB时钟            RCC_HCLKConfig
  5、设置高速APB时钟          RCC_PCLK2Config
  6、设置低速APB时钟          RCC_PCLK1Config
  7、设置PLL              RCC_PLLConfig
  8、打开PLL              RCC_PLLCmd(ENABLE)
  9、等待PLL工作            while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY)==RESET)
  10、设置系统时钟           RCC_SYSCLOCKConfig
  11、判断是否PLL是系统时钟      while(RCC_GetSYSCLKSource()!=0x08)
  12、打开要使用的外设时钟      RCC_APB2PerphClockCmd()/RCC_APB1PeriphClockCmd()
实例:
  1. /*******************************************************************************' Y7 r  Z3 E4 D) w/ d# l0 z/ `
  2. * Function Name  : RCC_Configuration
    , @% ]0 ]  P& @
  3. * Description    : Configures the different system clocks.0 U1 d" @* a: `- G) n
  4. * Input          : None
    2 C+ x, i% }' d9 w
  5. * Output         : None
    8 p4 m6 x/ H  B* y; a
  6. * Return         : None% J1 ^" Y% ]# O0 `, ~
  7. *******************************************************************************/8 P# d7 k4 {" z7 M
  8. void RCC_Configuration(void)
    9 ]' Z8 A& f7 G6 p- Y2 A) A4 p0 R
  9. {# j9 |/ x  C! i+ p2 D
  10.     /*------使用外部RC晶振----------*/
    + `( |' Z. e+ n+ W% N* N; P
  11.     RCC_DeInit();    //时钟默认初始化
    ' F6 a4 \! V. M, l
  12.     RCC_HSEConfig(RCC_HSE_ON);//使能外部的高速时钟7 N9 g% t1 R' l( y, j6 I
  13.     while(RCC_GetFlagStatus(RCC_FLAG_HSERDY) == RESET);//等待外部的高速时钟就绪
    ! a+ V- k1 ]! G2 t
  14. ( i: L! N5 Y; t, X$ ?+ c6 n: H: o4 b" Q
  15.     FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable); //使能指令预存取
    , H! Y. M" I6 A) [  g) o
  16.     FLASH_SetLatency(FLASH_Latency_2); //等待两个周期
    7 ~* f( a( M2 b. I* p, I
  17. ' d+ u- J( I# b8 \
  18.     RCC_HCLKConfig(RCC_SYSCLK_Div1); //设置AHB时钟为系统时钟8 z0 Y) t# s! F5 L% G+ |6 f
  19.     RCC_PCLK2Config(RCC_HCLK_Div1);     //设置APB2时钟为AHB时钟4 x0 R: z6 m9 T
  20.     RCC_PCLK1Config(RCC_HCLK_Div2);     //设置APB1时钟为AHB/2时钟+ [) y. H  f! B4 z6 q! Q% ]8 N
  21.     //以下3行是PLL的设置% X' O& j# a( S+ u, T- s) m1 }
  22.     RCC_PLLConfig(RCC_PLLSource_HSE_Div1,RCC_PLLMul_9);    //设置PLL时钟为外部高速时钟的9倍频. s8 y& `) {) G/ O
  23.     RCC_PLLCmd(ENABLE);    //使能PLL时钟
    * ?8 S' @. u; L; M
  24.     while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);    //等待PLL时钟使能就绪
    8 Q7 s- s6 e0 U9 P- h3 f; Z
  25.      //选择为PLL的CLOCK' Z' |" S  \! X- U# o* G' ?- B
  26.     RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);     //配置PLL时钟为系统时钟; \: x' F; y7 h1 p) h
  27.     while(RCC_GetSYSCLKSource()!=0x08);    //等待PLL时钟作为系统时钟
    9 ?7 k& S" \0 f# {5 C9 U. u
  28. 2 ~1 b3 D( F* |$ Q1 f. H
  29.     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC);
    - M' V- _3 R" H* g6 E  d# F
  30.     RCC_APB1PeriphClockCmd(RCC_APB1Periph_UASRT3,ENABLE);
    " H# x; T. V9 K/ _1 F( J  Q, Q% Y
  31. }
复制代码

3 h7 {0 U1 t4 R/ L. l: D) u) G, n7 \; l
RTC模块:
  RTC(Real_Time Clock)实时时钟;
实时时钟是一个独立的定时器,RTC模块拥有一组连续计数的计数器,在相应软件的配置下,可提供时钟日历的功能。修改计数器的值可以重新设置系统当前的时间和日期;
  RTC由两个主要部分组成。第一部分(APB1接口)用来和APB1总线相连。此单元包含一组16位寄存器,可通过APB1总线对其进行读写操作。APB1接口以APB1总线时钟为时钟;
  另一部分(RTC核)由一系列可编程计数器组成,分成两个主要模块;
    第一个模块是RTC的预分频模块,它可编程产生最长为1秒的RTC时间基准TR_CLK,RTC的预分频模块包含了一个20位的可编程分频器(RTC预分频器)。在每个TR_CLK周期中,如果在RTC_CR寄存器中设置了相应允许位,则RTC产生一个中断(秒中断)
    第二个模块是一个32位的可编程的计数器,它可以被初始化为当前的系统时钟时间。系统时间以TR_CLK速度增长并与存储在RTC_ALR寄存器中的可编程的时间相比较,如果RTC_CR控制寄存器设置了相应允许为则比较匹配时将产生一个闹钟中断;

' q* O6 y# D- \3 ?; b3 _' V
RTC主要特性:
  可编程的预分频系数:分频系数最高为220。
  32 位的可编程计数器,可用于较长时间段的测量。
    2个单独的时钟:用于APB1 接口的PCLK1 和RTC 时钟(此时的RTC 时钟必须小于
PCLK1 时钟的四分之一以上)
   2种独立的复位类型:
  ─ APB1 接口由系统复位
  ─ RTC 只能由后备域复位。
   3个专门的可屏蔽中断:
  ─ 闹钟中断,用来产生一个软件可编程的闹钟中断。
  ─ 秒中断,用来产生一个可编程的周期性中断信号(最长可达1 秒)。
  ─ 溢出中断,检测内部可编程计数器溢出并回转为0 的状态。

9 K& `( d( L) Y& a
302138309075011.png

3 W1 F( m5 A1 u% f2 i
RTC的一些设置是保存在后备区域中的:RTC_PRL, RTC_ALR, RTC_CNT 和RTC_DIV寄存器;
这些寄存器仅能通过备份复位信号复位,不受系统复位或电源复位的影响;
备份区域复位:
  当以下时间中之一发生时,产生备份区域复位:
    1、软件复位,备份区域复位可有设置备份区域控制器RCC_BDCR中的BDRST位产生;
    2、后备电池和系统电源都没电的情况下;引发备份区域复位;
配置RTC:
  RTC有两种模式(工作模式和配置模式),要对RTC进行配置,首先设置RTC处于设置模式下;通过对RTC_CRL寄存器中的CNF位置位使RTC进入配置模式;另外,对RTC的任何寄存器的写操作都必须在前一次写操作结束之后再进行,要使用软件来查询当前的状态,同可通过查询RTC_CR寄存器中的RT0FF状态位来判断RTC寄存器是否处于更新中,仅当RTOFF状态位是“1”时,RTC寄存器可写入新的值;(这些是对RTC的保护措施)
  配置过程:
    1、查询RTOFF位,直到RTOFF的值变为“1”
    2、置CNF值为1,进入配置模式;
    3、对一个或多个RTC寄存器进行写操作;
    4、清楚CNF标志位,退出配置模式;
    5、查询RTOFF,直到RTOFF位变为“1”,以确认写操作已经完成;
  仅当CNF标志位被清零时,写操作才能进行;这个过程至少需要3个RTCCLK周期;
配置实例:
  1. /*************************************************************************************: O$ A- x" W2 V1 Q- X
  2. **名称        ;void RTC_Configuration(void)7 ?( h2 l+ E5 B& a  B
  3. **功能        ;RTC实时时钟的配置
    & p4 Z1 D( l. O
  4. **入口参数    ;无
    , Z0 m  M8 e+ `) }5 S
  5. **出口参数    ;无+ i  I* R- h7 L* W
  6. *************************************************************************************/- r  A; v6 v; X2 |/ p: o

  7. ; Q, j5 w# U; |; k; q
  8. void RTC_Configuration(void)2 B8 j# f3 J% L$ X: X
  9. {
    ) ?) g5 w( Q) w
  10.     /* Enable PWR and BKP clocks */   //使能APB1外设PWR and BKP 的时钟
    ( e* d0 w, }1 y: y, N2 v. o/ C  D
  11.     /*打开电源和后备时钟*/1 m4 m1 R) k, e
  12.     RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP,ENABLE);8 o, U$ C) d. p/ N* t5 ~9 q+ {

  13. : a6 P' U' B/ Q4 \; M! W
  14.     /* Allow access to BKP Domain*/  //允许RTC 和后备区域寄存器的访问7 m: Q6 K: h7 J) y) K0 [4 w
  15.     PWR_BackupAccessCmd(ENABLE);
    ; w9 V" r  @  \' |$ k% @, C2 u3 L8 a
  16. 2 g! @0 ]' |$ g7 `
  17.     /* Reset Backup Domain*/        //将外设BKP的全部 寄存器重设为缺省值
    , x' h, k3 v9 j6 x/ h
  18.     BKP_DeInit();: G( O8 V! \& m
  19. # K2 ?* M: D2 l
  20.     /* Enable LSE */                //设置(打开)外部低速时钟$ Z" _. X- G7 s+ J& a3 x
  21.        RCC_LSEConfig(RCC_LSE_ON);
    $ _& Q% u( t' F1 ?

  22. 8 {! b6 z+ b, _6 Z5 a6 f# y
  23.     /* Wait till LSE is ready */        //等待外部低速时钟准备好; D1 h4 E+ @' B
  24.     while(RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET);+ v$ O- w* x0 V, Y

  25. ( O9 h( {" V$ {& S+ Y7 S
  26.     /* Select LSE as RTC Clock Source */    //设置LSE为RTC时钟
    2 k, G7 j' F# z: i3 ]% o
  27.     RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);/ i0 q4 V, Q( h7 F/ D$ ]" C
  28. ; _0 I) O7 t. q5 T$ {; O; S
  29.     /* Enable RTC Clock */                //使能RT时钟/ I; K! g1 B1 Q/ c! x
  30.     RCC_RTCCLKCmd(ENABLE);- |- j3 w4 S# a  _& T

  31. % \8 j4 \3 y% A4 g* M
  32.     //开始设置RTC,下面同步原因是:有两个时钟3 `8 Q  i* ]. s6 u4 I
  33.     /* Wait for RTC registers synchronization *///等待RTC寄存器(RTC_CNT,RTC_ALR and RTC_PRL)与RTC的APB时钟同步
    7 t2 Q' t1 O  z
  34.     RTC_WaitForSynchro();4 x8 P4 x& j% Q" b

  35. 7 N( o4 z* G6 d2 S
  36.     /* Wait untill last write operation on RTC register has finised *///等待最近一次对RTC的写操作完成
    ! e% z  p& O: X" [
  37.     RTC_WaitForLastTask();
    * }" a( _) _, P, F! B; L+ L' A

  38. # i+ f) r6 F8 K
  39.    /* Enable the RTC Second interrup */    //使能RTC的秒中断( l' b. R' h4 X2 W6 k2 x3 z) i
  40.    RTC_ITConfig(RTC_IT_SEC,ENABLE);
    1 i* ]+ Z" z4 Z) G: Y0 V' E

  41. 3 t  e5 U8 L  p8 ]$ V% e9 @( `
  42.    /* Wait untill last write operation on RTC register has finised */7 L% W6 t; {  x/ x  K7 Q2 m
  43.                                                             //等待最近一次对RTC的写操作完成) [5 c* d' {- r0 ]* H6 \! Z$ u
  44.     RTC_WaitForLastTask();
    % p9 N8 s9 e! M% m  V/ A; S3 a

  45. ' P3 K2 O: f+ A
  46.     //分频值为32767+1=32768
    ( Y9 l# D0 ?" d5 H+ g; z
  47.     //计数频率=(32.768khz/32768)= 1hz! N) X) B9 n. P9 N" _5 V
  48.    /* Set RTC prescaler : set RTC period to 1 sec*/        //设置RTC预分频的值
    / Z% z( [$ J+ n0 r  W
  49.    RTC_SetPrescaler(32767);
    + O) w/ U: b0 H5 y
  50. 9 \$ u& w: C0 l* m# l6 F
  51.     /* Wait untill last write operation on RTC register has finised */+ r2 Q$ ~- {4 v) P/ t
  52.                                                         //等待最近一次对RTC的写操作完成
    + L$ V6 w( ^  D: Q; P  ?
  53.     RTC_WaitForLastTask();7 g0 v6 U7 n2 D" q8 _$ H7 S; ]
  54. % R6 W" r% V" V5 p% G0 G  X
  55.     //设置当前的时间值
    * e/ L9 k1 x; e4 J+ Y( f3 y* x% v4 o, y
  56.     /*2014.4.5 10:20:44 |9 }# S! {- t5 b9 s" |
  57.     *t = 4+20*60+10*60*60 + 5*24*60*60+
    $ x  H; @3 W: h! L7 x2 p
  58.     *$ a6 o, G+ a4 `. |  |# i/ w% i
  59.     */
    - S- H( _6 B3 Z/ Z) Z" k2 F
  60.     RTC_SetCounter((u32)t);0 H2 p! p3 g. x' k& n* ], V
  61.     RTC_WaitForLastTask();
    7 A7 }0 O8 z: k5 _5 K6 H; U
  62. }
复制代码

6 |3 l" y9 p2 n* P
赞 收藏 评论0 发布时间:2022-1-22 17:54

举报

0个回答

所属标签

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版