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

关于STM32 RTC时钟使用内部/外部晶振的切换方法

[复制链接]
我不怕 发布时间:2019-1-8 15:45
    对于使用STM32单片开发项目的同志,经常会使用到STM32的RTC功能,而在配置RTC的功能时需要配置晶振的使用,可以使用内部晶振或外部晶振,配置流程参考官方的示例代码即可。
; C8 [" D8 p, t: s8 I    但在之前的项目中遇到一个问题,由于一些产品的外部晶振损坏(时间长了有些外部晶振容易坏掉),导致RTC实时时钟时间异常。为了降低公司的维护成本,所以考虑通过修改程序,重新配置为STM32内部晶振来解决问题(我们的应用场景可以采用这种方法,因为服务器会固定时间同步产品时间)。
" M9 h+ K: F9 K" g. _    采用外部晶振的RTC部分配置代码:
6 D+ J& w, B, H0 R+ K. _/ N    /* Enable the PWR clock */8 K( p8 r5 w# s3 u$ t3 @/ ]* w
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
9 L. E0 k( }3 H1 Y+ `+ ~! m; M7 n  /* Allow access to RTC */
9 n  a& ^0 d7 z& Z6 q3 Z  PWR_BackupAccessCmd(ENABLE);" N4 g1 q$ S. K( c1 @! m- T8 y4 I
    /* Enable the LSE OSC */1 X0 @" E( M0 N2 V5 T
  RCC_LSEConfig(RCC_LSE_ON);% s- \$ s( A2 _
   
+ I6 j  X# I  ~4 M- E7 ~- {; W    /* Wait till LSE is ready */
0 B$ [' ]& u3 M6 T    do{                            + R+ {9 t" l0 k2 `: V8 @$ s4 `
            tick++;
: D1 U. ^  g( ]6 V$ i' }; ?    }while(RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET && tick < 20000);
6 W; [8 L6 j6 _2 `    tick = 0;' {( A/ z+ n1 E" u0 ^* D0 B- V+ O4 Z: k
    /* Select the RTC Clock Source */2 N  q* `/ `- ?/ }
  RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);/ Y) v; G" v  S; T. }
    /* Enable the RTC Clock */
$ k+ J: s% C2 v5 B  RCC_RTCCLKCmd(ENABLE);8 B/ C2 M% O7 m+ @
    $ _% {0 W; C9 R$ h
    RTC_StructInit(&RTC_InitStructure);
, |1 T) y* X  t1 [( H5 s    RTC_Init(&RTC_InitStructure);- O* \2 ~! z1 S* Z" I6 P9 z
   
6 g/ y; ]' p7 L2 b! l    /* Wait for RTC APB registers synchronisation */
& I  `: Y! Y7 O1 s7 y# n4 J  RTC_WaitForSynchro();" x) @% X1 L9 g2 X! K/ \
    最初以为改为内部晶振配置比较简单,只要将和外部晶振有关的配置代码改为内部晶振即可。后来发现,STM32芯片的RTC时钟选择一旦配置了之后,想要切切换的话需要多配置一点东西,后来查了手册果然如此,这里给出配置代码,具体手册的说明有时间再放过来,以下部分供同志们参考。# _4 e* D1 H+ H8 }
    RTC从外部晶振切换为内部晶振配置代码:
( E* `4 P3 P; {3 W    uint32_t tick = 0;
: ]9 d  }2 R: x: U% t% U7 C    uint32_t tmpreg1 = 0;! _7 U0 L( T+ o
     2 u+ i3 u' @" q2 ?
    /* Enable the PWR clock */
/ [1 o% `  Q' G& |) P+ ]+ m0 h7 Q  RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);( Q0 G; o( h% X! p: H
  /* Allow access to RTC */
' }' y, G" l" f" Z3 h: s  PWR_BackupAccessCmd(ENABLE);; Q; I( x9 k3 G' N. p
    /* 晶振切换时必须执行的步骤,但不能每次上电都执行,否则会清空时间,同志们根据实际需求自行考虑执行位置 */) t/ i# D4 a4 o* H; o1 O( z
    tmpreg1 = (RCC->BDCR & ~(RCC_BDCR_RTCSEL));  Z) l- t/ O7 ~
    RCC_BackupResetCmd(ENABLE);        
0 ~- D! E, J" }    RCC_BackupResetCmd(DISABLE);( k/ D: [3 c) J; K
    RCC->BDCR = tmpreg1;

% _4 e5 n6 ^" w. M& L: M# E" m    ' j. u; y  h5 D% {7 F$ i/ }
   
' Y4 @# Z1 g& X  U; ~4 ]& Z' u    /* Enable the LSI OSC */
' p* V8 c' X. n5 W; A    RCC_LSICmd(ENABLE);0 A) G2 a+ G6 [$ A3 K0 H4 R- l# }
    /* Wait till LSI is ready */
5 f8 o& r  D# T3 w8 E  \! v    do{6 m: W7 v- O5 u! E( A# m& K" M" x
            
' G- t  x- Q, j0 j$ d! m, s) y            tick++;* K1 z- b7 J! h  W
    }while(RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET && tick < 20000);
: d1 X# M* x1 `5 B    tick = 0;6 i0 r% W/ X5 @, q( X
                  q! G3 v) b: g: R/ F& J
    /* Select the RTC Clock Source */! X' a+ n) |9 e  H) a; }2 O" u
  RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI);
& G0 F( d% h/ y    /* Enable the RTC Clock */0 |& u1 T. Z; S' d; l
  RCC_RTCCLKCmd(ENABLE);8 z3 |/ s/ k, l' h" K" j- X
   
+ }% A2 m6 ^4 J$ P/ C1 ~  m. W! K    RTC_StructInit(&RTC_InitStructure);* j! E5 r+ U2 m$ d  @
    RTC_Init(&RTC_InitStructure);
0 b/ V) Q8 W; o# P; x. P    ( Y- @2 T8 @) |# z
    /* Wait for RTC APB registers synchronisation */' @  R1 |! |/ u
  RTC_WaitForSynchro();
( g! f4 X; W$ I8 M
# W# u0 T" S% H7 t3 m天道酬勤!
6 x0 O+ n5 U  ]2 x+ ?4 N: i1 Y: Q4 `# N( x
收藏 评论1 发布时间:2019-1-8 15:45

举报

1个回答
五哥1 回答时间:2019-1-8 19:25:57
原子的程序不是这样写的,也能够在外部晶振损坏的情况下,调用内部的

所属标签

相似分享

关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版