对于使用STM32单片开发项目的同志,经常会使用到STM32的RTC功能,而在配置RTC的功能时需要配置晶振的使用,可以使用内部晶振或外部晶振,配置流程参考官方的示例代码即可。 但在之前的项目中遇到一个问题,由于一些产品的外部晶振损坏(时间长了有些外部晶振容易坏掉),导致RTC实时时钟时间异常。为了降低公司的维护成本,所以考虑通过修改程序,重新配置为STM32内部晶振来解决问题(我们的应用场景可以采用这种方法,因为服务器会固定时间同步产品时间)。 L% E; _1 @2 a, M7 ` 采用外部晶振的RTC部分配置代码:$ G6 R6 }; K. ?" K1 N /* Enable the PWR clock */ RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE); /* 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); 4 l5 Y! q* [( @# G4 X% @ /* Wait till LSE is ready */ 8 ^/ n2 L! P4 S do{ tick++; }while(RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET && tick < 20000); tick = 0; /* Select the RTC Clock Source */ RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE); /* Enable the RTC Clock */ RCC_RTCCLKCmd(ENABLE); 7 E# w' N* w* ^7 O RTC_StructInit(&RTC_InitStructure);! e$ k: a1 H! Y9 z2 ~ RTC_Init(&RTC_InitStructure); /* Wait for RTC APB registers synchronisation */! Q, S9 X5 d" ]2 J" Z$ m2 A RTC_WaitForSynchro(); 最初以为改为内部晶振配置比较简单,只要将和外部晶振有关的配置代码改为内部晶振即可。后来发现,STM32芯片的RTC时钟选择一旦配置了之后,想要切切换的话需要多配置一点东西,后来查了手册果然如此,这里给出配置代码,具体手册的说明有时间再放过来,以下部分供同志们参考。 RTC从外部晶振切换为内部晶振配置代码: uint32_t tick = 0;9 [: ^+ T+ B2 D5 r0 l$ F uint32_t tmpreg1 = 0;, p/ |( P$ }7 P /* Enable the PWR clock */ 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); RCC_BackupResetCmd(DISABLE);- m7 w! O$ {) w4 g0 L f9 @ RCC->BDCR = tmpreg1; /* Enable the LSI OSC */ RCC_LSICmd(ENABLE);# k$ z j$ l; Y/ l p+ a3 o /* Wait till LSI is ready */ do{ tick++;8 L# ]1 s+ ?' {3 r2 H3 V& b }while(RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET && tick < 20000); tick = 0;* ~4 f/ K# i; g7 j 5 Z& U& l+ ~! I* y( K; x /* Select the RTC Clock Source */ RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI); /* 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 /* Wait for RTC APB registers synchronisation *// L' V. d9 v# [$ U9 B RTC_WaitForSynchro();5 k ^; D0 E8 b. B3 d 天道酬勤!+ U3 m r9 E& Q! r3 n9 H |
原子的程序不是这样写的,也能够在外部晶振损坏的情况下,调用内部的 |