硬汉嵌入式论坛

 找回密码
 立即注册
查看: 4706|回复: 8
收起左侧

[有问必答] STM32F103 RTC 不保存日期,已加电池

[复制链接]

36

主题

142

回帖

255

积分

高级会员

积分
255
发表于 2020-7-8 09:56:40 | 显示全部楼层 |阅读模式
本帖最后由 takent 于 2020-7-8 10:01 编辑

当天调试RTC掉电是保存的,第二天查看RTC又是从默认日期开始了。
程序默认时钟是使用外部LSE,如果不起振就使用内部LSI。
备份寄存器掉电是保存的,说明电池没问题
下面是初始化的代码
  1. void bsp_InitRTC(void)
  2. {
  3.     uint16_t u16_WaitForOscSource;
  4.         uint16_t usTimeCnt = 0;
  5.         /*
  6.                 ÎòÃÇÔúBKPμÄo󱸼Ä′æÆ÷1ÖD£¬′æáËò»¸öìØêa×Ö·û0xA5A5, μúò»′ÎéÏμç»òoó±¸μçÔ′μôμço󣬸üÄ′æÆ÷êy¾Y¶aꧣ¬
  7.                 ±íÃ÷RTCêy¾Y¶aꧣ¬DèòaÖØDÂÅäÖÃ
  8.         */
  9.     if (BKP_ReadBackupRegister(BKP_DR1) != 0xA5A5)
  10.     {
  11.                 //ÖØDÂÅäÖÃRTC
  12.                 /* Enable PWR and BKP clocks */  /* PWRê±Öó£¨μçÔ′¿ØÖÆ£©óëBKPê±Öó£¨RTCo󱸼Ä′æÆ÷£©ê1Äü */  
  13.                 RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);
  14.                 /* Allow access to BKP Domain */ /*ê1ÄüRTCoío󱸼Ä′æÆ÷·ÃÎê */  
  15.                 PWR_BackupAccessCmd(ENABLE);
  16.                
  17.                 /* Reset Backup Domain */  /* ½«íaéèBKPμÄè«2¿¼Ä′æÆ÷ÖØéèÎaè±ê¡Öμ */   
  18.                 BKP_DeInit();
  19.                 /* Enable LSE */               
  20.                 RCC_LSEConfig(RCC_LSE_ON);
  21.                
  22.                 #if 0
  23.                 for(u16_WaitForOscSource=0; u16_WaitForOscSource < 5000; u16_WaitForOscSource++)
  24.                 {
  25.                         ;
  26.                 }
  27.                 #endif
  28.                
  29.                 /* Wait till LSE is ready */ /* μè′yía2&#191;&#190;§&#213;&#241;&#213;eμ′&#206;è&#182;¨ê&#228;3&#246; */  
  30.                 while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET)
  31.                 {
  32.                         bsp_DelayMS(1);
  33.                         usTimeCnt++;
  34.                         if(usTimeCnt >= RTC_WAIT_TIME)
  35.                         {
  36.                                 break;
  37.                         }
  38.                 }
  39.                
  40.                 if(usTimeCnt >= RTC_WAIT_TIME)
  41.                 {
  42.                         /* 1&#216;±&#213;LSE */               
  43.                         RCC_LSEConfig(RCC_LSE_OFF);       
  44.                        
  45.                         /* ê1&#196;üLSI */
  46.                         RCC_LSICmd(ENABLE);

  47.                         /* μè′y&#214;±μ&#189;LSI&#190;íD÷ */
  48.                         while (RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET);

  49.                         /* &#209;&#161;&#212;&#241;LSI×÷&#206;aRTCμ&#196;ê±&#214;ó */
  50.                         RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI);                               
  51.                        
  52.                 }
  53.                 else
  54.                 {
  55.                         /* Select LSE as RTC Clock Source */ /*ê1ó&#195;ía2&#191;32.768KHz&#190;§&#213;&#241;×÷&#206;aRTCê±&#214;ó */
  56.                         RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);               
  57.                 }
  58.                
  59.                 /* Enable RTC Clock */
  60.                 RCC_RTCCLKCmd(ENABLE);
  61.                 /* Wait for RTC registers synchronization */
  62.                 RTC_WaitForSynchro();
  63.                 /* Wait until last write operation on RTC registers has finished */
  64.                 RTC_WaitForLastTask();
  65.                 /* Enable the RTC Second */
  66.                 RTC_ITConfig(RTC_IT_SEC, ENABLE);
  67.                 /* Wait until last write operation on RTC registers has finished */
  68.                 RTC_WaitForLastTask();
  69.                
  70.         //        RTC_EnterConfigMode();
  71.                
  72.                 if(usTimeCnt >= RTC_WAIT_TIME)
  73.                 {
  74.                         /*
  75.                           1. LSIμ&#196;&#198;μ&#194;êμ&#228;Dí&#214;μê&#199;40KHz(30KHzμ&#189;60KHz)
  76.                           2. &#213;aà&#239;°′40KHzà′&#188;&#198;&#203;&#227;
  77.                                  RTC &#214;ü&#198;ú = RTCCLK / RTC_PR = (40 KHz)/(39999 + 1) = 1Hz
  78.                         */
  79.                         RTC_SetPrescaler(39999);                
  80.                 }
  81.                 else
  82.                 {
  83.                         /* Set RTC prescaler: set RTC period to 1sec */   
  84.                         /* 32.768KHz&#190;§&#213;&#241;&#212;¤·&#214;&#198;μ&#214;μê&#199;32767,è&#231;1&#251;&#182;&#212;&#190;&#171;&#182;èòa&#199;óoü&#184;&#223;&#191;éò&#212;DT&#184;&#196;′&#203;·&#214;&#198;μ&#214;μà′D£×&#188;&#190;§&#213;&#241; */
  85.                         RTC_SetPrescaler(32767); /* RTC period = RTCCLK/RTC_PR = (32.768 KHz)/(32767+1) */               
  86.                 }
  87.                
  88.                 /* Wait until last write operation on RTC registers has finished */
  89.                 RTC_WaitForLastTask();
  90.                
  91.                 RTC_WriteClock(DEFAULT_RTC_YEAR, DEFAULT_RTC_MON, DEFAULT_RTC_DAY,
  92.                                                 DEFAULT_RTC_HOUR, DEFAULT_RTC_MIN, DEFAULT_RTC_SEC);//&#196;&#172;è&#207;ê±&#188;&#228;
  93.                
  94.         /* &#197;&#228;&#214;&#195;íê3éoó£&#172;&#207;òoó±&#184;&#188;&#196;′&#230;&#198;÷&#214;DD′ì&#216;êa×&#214;·&#251;0xA5A5 */
  95.         BKP_WriteBackupRegister(BKP_DR1, 0xA5A5);
  96.     }
  97.     else
  98.         {
  99.                 /* è&#244;oó±&#184;&#188;&#196;′&#230;&#198;÷&#195;&#187;óDμ&#244;μ&#231;£&#172;&#212;ò&#206;TDè&#214;&#216;D&#194;&#197;&#228;&#214;&#195;RTC */
  100.                 RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);
  101.                 /* Allow access to BKP Domain */ /*ê1&#196;üRTCoíoó±&#184;&#188;&#196;′&#230;&#198;÷·&#195;&#206;ê */  
  102.                 PWR_BackupAccessCmd(ENABLE);               
  103.                 for (u16_WaitForOscSource = 0; u16_WaitForOscSource < 5000; u16_WaitForOscSource++)
  104.                 {
  105.                         ;
  106.                 }
  107.         if (RCC_GetFlagStatus(RCC_FLAG_PORRST) != RESET)
  108.         {
  109.                         /* é&#207;μ&#231;&#184;′&#206;&#187; */
  110.         }
  111.         else if (RCC_GetFlagStatus(RCC_FLAG_PINRST) != RESET)
  112.         {
  113.             /* ía2&#191;RST1ü&#189;&#197;&#184;′&#206;&#187; */
  114.         }
  115.         /* &#199;&#229;3yRCC&#214;D&#184;′&#206;&#187;±ê&#214;&#190; */
  116.         RCC_ClearFlag();
  117.         
  118.                 //&#203;&#228;è&#187;RTC&#196;£&#191;é2&#187;Dèòa&#214;&#216;D&#194;&#197;&#228;&#214;&#195;£&#172;&#199;òμ&#244;μ&#231;oóòà&#191;&#191;oó±&#184;μ&#231;3&#216;òàè&#187;&#212;&#203;DD
  119.         //μ&#171;ê&#199;&#195;&#191;′&#206;é&#207;μ&#231;oó£&#172;&#187;1ê&#199;òaê1&#196;üRTCCLK???????
  120.         //RCC_RTCCLKCmd(ENABLE);
  121.         //μè′yRTCê±&#214;óó&#235;APB1ê±&#214;óí&#172;2&#189;
  122.         //RTC_WaitForSynchro();
  123.         
  124.         //ê1&#196;ü&#195;&#235;&#214;D&#182;&#207;
  125.         //RTC_ITConfig(RTC_IT_SEC, ENABLE);
  126.         
  127.         //μè′y2ù×÷íê3é
  128.         RTC_WaitForLastTask();
  129.     }
  130.         return;
  131. }
复制代码


bsp_cpu_rtc.c

11.93 KB, 下载次数: 9

回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107397
QQ
发表于 2020-7-8 10:43:56 | 显示全部楼层
看下是不是跳转到重新配置里面了。
回复

使用道具 举报

36

主题

142

回帖

255

积分

高级会员

积分
255
 楼主| 发表于 2020-7-8 10:49:15 | 显示全部楼层
eric2013 发表于 2020-7-8 10:43
看下是不是跳转到重新配置里面了。

备份寄存器掉电保存没问题,所以不会重新配置。
百度了一下,估计外部RTC晶振不起,使用内部LSI,掉电是不保存的。艾,STM32的RTC尽量不要用
http://blog.chinaunix.net/uid-27106528-id-4288509.html
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107397
QQ
发表于 2020-7-8 11:56:53 | 显示全部楼层
takent 发表于 2020-7-8 10:49
备份寄存器掉电保存没问题,所以不会重新配置。
百度了一下,估计外部RTC晶振不起,使用内部LSI,掉电是 ...

重新看了下你的问题,明白了。

你是LSE不能用的时候切换到LSI的骚操作。。。
回复

使用道具 举报

36

主题

142

回帖

255

积分

高级会员

积分
255
 楼主| 发表于 2020-7-8 12:12:00 | 显示全部楼层
eric2013 发表于 2020-7-8 11:56
重新看了下你的问题,明白了。

你是LSE不能用的时候切换到LSI的骚操作。。。

是的,STM32的RTC起振问题一直存在没解决,通病
回复

使用道具 举报

336

主题

2042

回帖

3055

积分

版主

Rank: 7Rank: 7Rank: 7

积分
3055
发表于 2020-7-8 13:58:19 | 显示全部楼层
本帖最后由 caicaptain2 于 2020-7-8 14:00 编辑
takent 发表于 2020-7-8 10:49
备份寄存器掉电保存没问题,所以不会重新配置。
百度了一下,估计外部RTC晶振不起,使用内部LSI,掉电是 ...

使用专用的晶振就好了。 就是爱普生的那个6pf的MC306。 就是个头比较大! 我用了几百片,全通过。
别的牌子不要用。
现在有很多3215封装的32768KHz的,封装很小巧,漂亮,可惜我没敢用过。
回复

使用道具 举报

36

主题

142

回帖

255

积分

高级会员

积分
255
 楼主| 发表于 2020-7-8 15:29:58 | 显示全部楼层
两个外部负载电容10P吗, 我一直都用小封装
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107397
QQ
发表于 2020-7-9 09:00:27 | 显示全部楼层
takent 发表于 2020-7-8 15:29
两个外部负载电容10P吗, 我一直都用小封装

STM32的振荡器设计指南应用笔记AN2867,中文版和英文版以及强烈推荐的32768晶振型号
http://www.armbbs.cn/forum.php?m ... 7673&fromuid=58
(出处: 硬汉嵌入式论坛)
回复

使用道具 举报

336

主题

2042

回帖

3055

积分

版主

Rank: 7Rank: 7Rank: 7

积分
3055
发表于 2020-7-9 10:51:23 | 显示全部楼层
takent 发表于 2020-7-8 15:29
两个外部负载电容10P吗, 我一直都用小封装

可以参照安富莱的硬件电路图,他们做的电路板更多,都很好的。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-5-30 06:09 , Processed in 0.182400 second(s), 28 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表