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

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

[复制链接]
我不怕 发布时间:2019-1-8 15:45
    对于使用STM32单片开发项目的同志,经常会使用到STM32的RTC功能,而在配置RTC的功能时需要配置晶振的使用,可以使用内部晶振或外部晶振,配置流程参考官方的示例代码即可。
; p5 i2 s5 a6 X5 l* c! o$ r    但在之前的项目中遇到一个问题,由于一些产品的外部晶振损坏(时间长了有些外部晶振容易坏掉),导致RTC实时时钟时间异常。为了降低公司的维护成本,所以考虑通过修改程序,重新配置为STM32内部晶振来解决问题(我们的应用场景可以采用这种方法,因为服务器会固定时间同步产品时间)。  L% E; _1 @2 a, M7 `
    采用外部晶振的RTC部分配置代码:$ G6 R6 }; K. ?" K1 N
    /* Enable the PWR clock */
, K( B+ M. i* H# {' t  RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
8 _  Z; b( c4 s, w, W  /* Allow access to RTC */- l: Z6 U6 s! q( g! c
  PWR_BackupAccessCmd(ENABLE);- v+ E4 d, q. R, c3 K
    /* Enable the LSE OSC */. v- {/ r8 y/ J# _9 H. z" m! K4 J7 C
  RCC_LSEConfig(RCC_LSE_ON);
( f) h/ t4 x. r. E7 x( I2 C& s( P    4 l5 Y! q* [( @# G4 X% @
    /* Wait till LSE is ready */ 8 ^/ n2 L! P4 S
    do{                           
  P8 O  {4 @- g" d$ M+ B, H            tick++;
% w9 b9 g7 v  @+ ^# Q, U    }while(RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET && tick < 20000);
, A8 P! J  F8 ^. J    tick = 0;
& ~- g# U5 {9 q8 _& n5 ]. Z    /* Select the RTC Clock Source */
7 X) p9 w, `, a2 X: ?  RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);
( O+ i/ M! @& H3 o    /* Enable the RTC Clock */
" s! E1 P" \" ?9 M# ]% _  RCC_RTCCLKCmd(ENABLE);
2 ?3 T; o$ K2 d    7 E# w' N* w* ^7 O
    RTC_StructInit(&RTC_InitStructure);! e$ k: a1 H! Y9 z2 ~
    RTC_Init(&RTC_InitStructure);
' p* L' ^( C" H9 O  t7 [   
# n% h& Y; B+ {- ^  X    /* Wait for RTC APB registers synchronisation */! Q, S9 X5 d" ]2 J" Z$ m2 A
  RTC_WaitForSynchro();
2 X: |0 L8 S: W' j8 k. n- O9 g    最初以为改为内部晶振配置比较简单,只要将和外部晶振有关的配置代码改为内部晶振即可。后来发现,STM32芯片的RTC时钟选择一旦配置了之后,想要切切换的话需要多配置一点东西,后来查了手册果然如此,这里给出配置代码,具体手册的说明有时间再放过来,以下部分供同志们参考。
# K9 D3 @& Y$ @  I" t    RTC从外部晶振切换为内部晶振配置代码:
) ^2 z% W  _1 @    uint32_t tick = 0;9 [: ^+ T+ B2 D5 r0 l$ F
    uint32_t tmpreg1 = 0;, p/ |( P$ }7 P
     
( q, ?* r+ {( [7 V! d) \    /* Enable the PWR clock */
; H2 o$ o: {4 L5 U% S  RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);. {% s4 r  Z, A0 k# _
  /* Allow access to RTC */' N6 R6 Z( K  P% l9 h$ v+ s3 q
  PWR_BackupAccessCmd(ENABLE);; I3 B: a7 _6 J7 S7 I* J# ~
    /* 晶振切换时必须执行的步骤,但不能每次上电都执行,否则会清空时间,同志们根据实际需求自行考虑执行位置 */9 c# X5 h# f8 S" a: @( d8 E! y
    tmpreg1 = (RCC->BDCR & ~(RCC_BDCR_RTCSEL));, o, H6 a+ N) s: w, p% q
    RCC_BackupResetCmd(ENABLE);        
2 o. k; p' P5 d0 G$ e8 M    RCC_BackupResetCmd(DISABLE);- m7 w! O$ {) w4 g0 L  f9 @
    RCC->BDCR = tmpreg1;

$ K3 i* ^# G: k; l9 _  I6 V   
6 V4 b9 v2 r, F2 ]8 d   
# Z$ o/ b9 B- r! w    /* Enable the LSI OSC */
* P" N8 V* J+ J( z; s    RCC_LSICmd(ENABLE);# k$ z  j$ l; Y/ l  p+ a3 o
    /* Wait till LSI is ready */
- y# ~: v, g' l4 h0 r: K: ^% \    do{
( T/ N3 _; C9 Z- ]            
8 B8 N* N% h7 Z7 N5 X            tick++;8 L# ]1 s+ ?' {3 r2 H3 V& b
    }while(RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET && tick < 20000);
- W) G3 ]# J; e0 S% U    tick = 0;* ~4 f/ K# i; g7 j
                5 Z& U& l+ ~! I* y( K; x
    /* Select the RTC Clock Source */
/ V$ c2 T  r  ~8 A( S  RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI);
& X; }6 @; V4 ]$ x) S8 g    /* Enable the RTC Clock */2 k, H- |8 e/ K3 R1 s
  RCC_RTCCLKCmd(ENABLE);+ ?# a+ {8 W5 m) H( k( c" X6 _# C& l
    8 s- o1 n8 x# g" `1 R" t
    RTC_StructInit(&RTC_InitStructure);* a2 {4 O& G' x2 z
    RTC_Init(&RTC_InitStructure);% o  D( j! ]" S0 b
   
; S% \8 P# l9 M4 N6 T9 l: K    /* Wait for RTC APB registers synchronisation *// L' V. d9 v# [$ U9 B
  RTC_WaitForSynchro();5 k  ^; D0 E8 b. B3 d

4 U8 w# N; g) P# F  T% i3 l+ y天道酬勤!+ U3 m  r9 E& Q! r3 n9 H

* Q: X' M8 k, t  Q
收藏 评论1 发布时间:2019-1-8 15:45

举报

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

所属标签

相似分享

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