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

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

[复制链接]
我不怕 发布时间:2019-1-8 15:45
    对于使用STM32单片开发项目的同志,经常会使用到STM32的RTC功能,而在配置RTC的功能时需要配置晶振的使用,可以使用内部晶振或外部晶振,配置流程参考官方的示例代码即可。
( m4 _5 b+ l0 ~- w" I# w* z9 b$ @8 P7 w# r    但在之前的项目中遇到一个问题,由于一些产品的外部晶振损坏(时间长了有些外部晶振容易坏掉),导致RTC实时时钟时间异常。为了降低公司的维护成本,所以考虑通过修改程序,重新配置为STM32内部晶振来解决问题(我们的应用场景可以采用这种方法,因为服务器会固定时间同步产品时间)。. R. `* u0 r3 v( H3 Q1 t
    采用外部晶振的RTC部分配置代码:' P8 W% X8 K. u! Y, F. p$ Y9 J
    /* Enable the PWR clock */) X9 C4 V: _/ ^) E; W3 u# P
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
' \: a" _9 z' `2 y! k8 r- W  /* Allow access to RTC */
' p! [3 A% T4 E( U$ ~: s$ |& I  PWR_BackupAccessCmd(ENABLE);6 W' [( B! s& R  O; W
    /* Enable the LSE OSC */5 D; A* q, v2 x7 p5 w- W' f
  RCC_LSEConfig(RCC_LSE_ON);* d. [8 k! ~  E4 z7 G. [/ W
   
* ^/ S' v, S" S3 @    /* Wait till LSE is ready */
! ^$ d5 p3 c2 h4 K- S# p    do{                           
$ m! i4 o4 {+ {6 q; @4 a9 u& m            tick++;
$ `5 o& _. u* i3 {, N  c    }while(RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET && tick < 20000);# D4 z' ?  D- l: H. s' t. [
    tick = 0;8 e0 |# s- r8 y* ?: E# ]
    /* Select the RTC Clock Source */* B8 z  O: z+ I: ^
  RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);
1 N! t: |# [0 J  Y- H7 ?5 ^    /* Enable the RTC Clock */
5 ^/ _  q! x# \6 W4 \3 Q0 i5 [  RCC_RTCCLKCmd(ENABLE);
! g, o8 V% _2 G1 ?" k" ?4 Q2 b    0 d% K& A  t: C  i7 J7 ]% ^4 D* c
    RTC_StructInit(&RTC_InitStructure);+ H. J. E+ x1 H5 [% i
    RTC_Init(&RTC_InitStructure);/ y+ w/ L. M% n5 g
   
* x4 V; l. Q. j- c    /* Wait for RTC APB registers synchronisation */
1 V" |# w5 _" A$ R4 ]  RTC_WaitForSynchro();6 W( r3 `* W* ^  U
    最初以为改为内部晶振配置比较简单,只要将和外部晶振有关的配置代码改为内部晶振即可。后来发现,STM32芯片的RTC时钟选择一旦配置了之后,想要切切换的话需要多配置一点东西,后来查了手册果然如此,这里给出配置代码,具体手册的说明有时间再放过来,以下部分供同志们参考。
. }9 K% i7 E1 \: j% Z: d    RTC从外部晶振切换为内部晶振配置代码:+ ]/ D  N4 s! |
    uint32_t tick = 0;
2 P# \0 r& x" d) P1 f: Z9 F    uint32_t tmpreg1 = 0;) L7 X' j8 U- N
     
! A# U6 y( r1 ^- J4 x# C    /* Enable the PWR clock */6 k: A9 G0 C, w' R+ Q* p4 P  y' ?
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);7 ]' k9 D# l' I) \# o2 G- [
  /* Allow access to RTC */
6 E/ k# c& B7 y1 o% o  PWR_BackupAccessCmd(ENABLE);) _- z4 C! i* ]8 T' f
    /* 晶振切换时必须执行的步骤,但不能每次上电都执行,否则会清空时间,同志们根据实际需求自行考虑执行位置 */
# ], D! j' O+ R1 f4 [    tmpreg1 = (RCC->BDCR & ~(RCC_BDCR_RTCSEL));
  h* T% g# R  g' g+ Q    RCC_BackupResetCmd(ENABLE);        1 v4 u  A2 f3 y) E, H4 S
    RCC_BackupResetCmd(DISABLE);0 o8 ~2 @; Q6 h. h
    RCC->BDCR = tmpreg1;

) S! ]7 P9 ]8 e" c4 |  c8 c& @+ J   
: e- j8 @7 ~& a. y, s, R    8 C" {4 J- M1 t7 X; e' \( ~  f
    /* Enable the LSI OSC */+ f0 v% K4 J( X4 Q  a
    RCC_LSICmd(ENABLE);: R& z! ?! w' e$ x6 `
    /* Wait till LSI is ready */ - p: n" R+ o! f3 Q
    do{- }! Q) e1 R! N0 R% K( N
            ; Z- t+ R, T9 r5 {" H& c# \8 f3 y# m
            tick++;1 v% |4 L/ L, [# E1 j
    }while(RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET && tick < 20000);
8 u- h. z+ Z( \% H; C9 s    tick = 0;
. g" K+ c: v1 w* q! k; ?               
* E- P. @% d8 C. a3 C! M    /* Select the RTC Clock Source */. f! n0 T3 e/ Z
  RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI);
. ~% W$ _8 `7 v. N    /* Enable the RTC Clock */9 M% S$ C7 O8 K# p
  RCC_RTCCLKCmd(ENABLE);* |( H" @. Y- [+ \+ R5 D! w
   
  l! {, O$ K/ C( g  Z    RTC_StructInit(&RTC_InitStructure);
9 g* g! Z/ F* f: l    RTC_Init(&RTC_InitStructure);
# W1 Q5 y; b/ b  L$ y   
0 Q- P5 z! p* J' |: E3 R; J    /* Wait for RTC APB registers synchronisation */
! f! i/ s/ U, R% J& d1 V  RTC_WaitForSynchro();
# C! |8 z; z4 V7 b! t) M* C6 x) e  u
天道酬勤!  j- U% X6 B4 C" E

7 N8 h( T% C0 v% a
收藏 评论1 发布时间:2019-1-8 15:45

举报

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

所属标签

相似分享

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