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

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

[复制链接]
我不怕 发布时间:2019-1-8 15:45
    对于使用STM32单片开发项目的同志,经常会使用到STM32的RTC功能,而在配置RTC的功能时需要配置晶振的使用,可以使用内部晶振或外部晶振,配置流程参考官方的示例代码即可。
& G/ _: a3 q7 X    但在之前的项目中遇到一个问题,由于一些产品的外部晶振损坏(时间长了有些外部晶振容易坏掉),导致RTC实时时钟时间异常。为了降低公司的维护成本,所以考虑通过修改程序,重新配置为STM32内部晶振来解决问题(我们的应用场景可以采用这种方法,因为服务器会固定时间同步产品时间)。: A! o3 ]6 x3 M& S
    采用外部晶振的RTC部分配置代码:: H7 H  ~/ u, |9 N& A) L
    /* Enable the PWR clock */
) T% G# N7 l, R9 o7 H  RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
  d6 @: K5 g+ G7 z- u  /* Allow access to RTC */+ |' P+ l3 D9 @. l! J. K; }* Q
  PWR_BackupAccessCmd(ENABLE);
1 {0 W; P8 z% M  @" D    /* Enable the LSE OSC */) ^9 }6 e' \. e
  RCC_LSEConfig(RCC_LSE_ON);4 j. {  e7 U, O* P6 `) q! m3 o
    % R% s' T+ H3 h# j8 ]
    /* Wait till LSE is ready */ & H3 ]) T8 c& v" {
    do{                           
% r; @9 [+ v  P5 A; d4 j            tick++;
) O2 _5 [7 u! w2 `3 _    }while(RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET && tick < 20000);* D) x. A# k& |" ~$ s1 Z
    tick = 0;
$ a- L+ t$ {' M# t3 Q  p, k    /* Select the RTC Clock Source */
+ C  ]# M6 z) V$ |. c  RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);
! I* I& r# M# ]" S, E/ r    /* Enable the RTC Clock */
# Q7 m- ]9 p" Z1 p" N. {. D  RCC_RTCCLKCmd(ENABLE);
. U- ^: Y$ ^4 S, @3 @% Q2 V" B   
- F8 u+ L! ~2 W    RTC_StructInit(&RTC_InitStructure);
: a3 K0 l4 M0 Q4 ?    RTC_Init(&RTC_InitStructure);
: K7 H; b. ^8 y, _/ n, Z. F) A0 r    7 }/ t  i5 \. b% B
    /* Wait for RTC APB registers synchronisation */
7 x8 `" t7 h9 {: {1 D+ P  RTC_WaitForSynchro();
9 {$ O% M7 Y! D; A" v    最初以为改为内部晶振配置比较简单,只要将和外部晶振有关的配置代码改为内部晶振即可。后来发现,STM32芯片的RTC时钟选择一旦配置了之后,想要切切换的话需要多配置一点东西,后来查了手册果然如此,这里给出配置代码,具体手册的说明有时间再放过来,以下部分供同志们参考。6 i* B7 g9 z" v2 c& ?6 p
    RTC从外部晶振切换为内部晶振配置代码:- ^, y3 |1 B6 L" [" `- B4 ?
    uint32_t tick = 0;
9 x( J: b4 N1 U& G9 U& p# J/ r6 J    uint32_t tmpreg1 = 0;' J  d$ ?% R! f; N8 J% g* R
     * N. M, b. d- ^5 U
    /* Enable the PWR clock */$ |" |; H) I1 s: F9 s% n
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
( n4 B. d# y4 R, a! a  /* Allow access to RTC */+ H3 D+ b3 X- m7 u& z9 g
  PWR_BackupAccessCmd(ENABLE);
) A4 U  m+ f3 Z( B    /* 晶振切换时必须执行的步骤,但不能每次上电都执行,否则会清空时间,同志们根据实际需求自行考虑执行位置 */
" ?- ]% b/ T6 I0 i( U) d; p# E    tmpreg1 = (RCC->BDCR & ~(RCC_BDCR_RTCSEL));
( n& h' k( J! S$ j4 m+ I3 Q" ^    RCC_BackupResetCmd(ENABLE);        - C  j7 r- `. s1 ^
    RCC_BackupResetCmd(DISABLE);* k; \) N! n% ^- w  n
    RCC->BDCR = tmpreg1;
$ N3 `0 W& f' g) X" z4 A: `7 J
    4 h, X/ K( [3 n' g2 V
   
- [  c8 O# t  D$ B$ R    /* Enable the LSI OSC */
/ \, _2 B* P$ ^8 C$ @. f    RCC_LSICmd(ENABLE);, z) [/ }% s8 C( W4 T
    /* Wait till LSI is ready */ 1 r) ]) r7 y3 A* w9 }% ^
    do{
+ I  V9 e) g  q1 k" _  M              a. l5 k0 [& t8 N
            tick++;. k! K; y) k; A. ~2 Q
    }while(RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET && tick < 20000);
# X; h3 G( o- d9 S    tick = 0;* S+ {8 d/ Y, u5 I1 f$ ]0 _3 W
                7 j4 f" [* j! S9 l' |
    /* Select the RTC Clock Source */
/ g8 }# r8 F+ o/ s  RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI);
  |. T/ i3 K# d    /* Enable the RTC Clock */0 k& ?  \& M* U/ F8 G. w
  RCC_RTCCLKCmd(ENABLE);
& i& M  t( i* d# B3 S. W   
' o* k: n. [( t( _: Y5 v    RTC_StructInit(&RTC_InitStructure);" h* ?& n8 l; C  \
    RTC_Init(&RTC_InitStructure);
. b* |+ [0 c! {0 W* r  x( C1 ~" V   
/ P, d* m- s: |. g# h1 D    /* Wait for RTC APB registers synchronisation */! u4 }8 n' c8 f7 s5 B
  RTC_WaitForSynchro();
0 g- W  o/ A1 A% c2 {
9 N$ Q% M3 y6 z  b( B* R天道酬勤!5 s9 `' x8 V: S8 Q

0 `' }( U% Y8 @, f. h% v
收藏 评论1 发布时间:2019-1-8 15:45

举报

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

所属标签

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