打印

STM32F407 RTC断电后只用电池供电,如何配置?是否需特殊寄存器的配置

[复制链接]
14021|15
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
云仔|  楼主 | 2013-5-16 19:59 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
最近在用STM32F407的芯片画的板子,RTC这块功能一直不能实现,问题主要表现:1、有主供电的时候,能够正常计时。断电后只有电池供电,隔一段时间再上电读取RTC时间仍是我程序中初始化设置中的时间。但加断点观察并没有运行初始化设置时间的函数。不知道什么原因?有没有人碰到过啊!
贴程序:
if (RTC_ReadBackupRegister(RTC_BKP_DR0) != 0x32F2)     //读RTC时间备份寄存器DR0的值判断是否是第一次配置,以防上电重新配置。如果=0x32F2 表示前面配置过,无需再配置。
  {
    flag_rtc=RTC_ReadBackupRegister(RTC_BKP_DR0);//wu add 5 4
    /* RTC configuration  */
    RTC_Config();

    /* Configure the RTC data register and RTC prescaler */
    RTC_InitStructure.RTC_AsynchPrediv = AsynchPrediv;
    RTC_InitStructure.RTC_SynchPrediv = SynchPrediv;
    RTC_InitStructure.RTC_HourFormat = RTC_HourFormat_24;   //时间格式为24H
   
    /* Check on RTC init */
    if (RTC_Init(&RTC_InitStructure) == ERROR)
    {
    //  printf("\n\r        /!\\***** RTC Prescaler Config failed ********/!\\ \n\r");
    }

    /* Configure the time register */
     
    RTC_TimeRegulate();           //给寄存器设定初始时间值
/*  Backup SRAM ********wu add 5 14*******************************************************/
  /* Enable BKPRAM Clock */
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_BKPSRAM, ENABLE);

  /* Write to Backup SRAM with 32-Bit Data */
    for (i = 0x0; i < 0x1000; i += 4)
  {
    *(__IO uint32_t *) (BKPSRAM_BASE + i) = i;
  }
  /* Check the written Data */
  for (i = 0x0; i < 0x1000; i += 4)
  {
    if ((*(__IO uint32_t *) (BKPSRAM_BASE + i)) != i)
    {
      errorindex++;
    }
  }

/* Enable the Backup SRAM low power Regulator to retain it's content in VBAT mode */
  PWR_BackupRegulatorCmd(ENABLE);
  /* Wait until the Backup SRAM low power Regulator is ready */
  while(PWR_GetFlagStatus(PWR_FLAG_BRR) == RESET)
  {
  }

/*********************************************************/   

  }
  else                    //不是第一次配置。      
  {
    flag_rtc=RTC_ReadBackupRegister(RTC_BKP_DR0);//wu add 5 4
    /* Check if the Power On Reset flag is set */
    if (RCC_GetFlagStatus(RCC_FLAG_PORRST) != RESET)
    {
    }
    /* Check if the Pin Reset flag is set */
    else if (RCC_GetFlagStatus(RCC_FLAG_PINRST) != RESET)
    {
    }  
    /* Enable the PWR clock */
//    RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
    /*  Backup SRAM ***************************************************************/
    /* Enable BKPSRAM Clock */
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_BKPSRAM, ENABLE);

    /* Check the written Data */
    for (i = 0x0; i < 0x1000; i += 4)
    {
      if ((*(__IO uint32_t *) (BKPSRAM_BASE + i)) != i)
      {
        errorindex++;
      }
    }
   
    /* Allow access to RTC 后备域解锁*/
    PWR_BackupAccessCmd(ENABLE);                                                   

    /* Wait for RTC APB registers synchronisation等待RTC时间寄存器的值与APB时钟同步 */
    RTC_WaitForSynchro();
    /* Clear the RTC Alarm Flag */
    RTC_ClearFlag(RTC_FLAG_ALRAF);

    /* Clear the EXTI Line 17 Pending bit (Connected internally to RTC Alarm) */
   // EXTI_ClearITPendingBit(EXTI_Line17);

               
  }
沙发
云仔|  楼主 | 2013-5-16 20:01 | 只看该作者
补充一下,RTC时钟选的LSE外部32.768K晶振

使用特权

评论回复
板凳
云仔|  楼主 | 2013-5-16 20:11 | 只看该作者
补充一下函数
void RTC_Config(void)
{
  /* Enable the PWR clock */
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
//  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_BKPSRAM, ENABLE);  //wu ADD 5 5
  
/* Allow access to RTC 后备域解锁*/
  PWR_BackupAccessCmd(ENABLE);                                                
  
#if defined (RTC_CLOCK_SOURCE_LSI)  /* LSI used as RTC source clock*/
/* The RTC Clock may varies due to LSI frequency dispersion. */   
  /* Enable the LSI OSC */
  RCC_LSICmd(ENABLE);

  /* Wait till LSI is ready */  
  while(RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET)
  {
  }

  /* Select the RTC Clock Source */
  RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI);
  
  SynchPrediv = 0xFF;
  AsynchPrediv = 0x7F;

#elif defined (RTC_CLOCK_SOURCE_LSE) /* LSE used as RTC source clock */
  /* Enable the LSE OSC */
  RCC_LSEConfig(RCC_LSE_ON);

  /* Wait till LSE is ready */  

  while(RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET)
  {
  }

  /* Select the RTC Clock Source */
  RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);   
  SynchPrediv = 0xFF;
  AsynchPrediv = 0x7F;

#else
  #error Please select the RTC Clock source inside the main.c file
#endif /* RTC_CLOCK_SOURCE_LSI */
  
  /* Enable the RTC Clock */
  RCC_RTCCLKCmd(ENABLE);

  /* Wait for RTC APB registers synchronisation */
  RTC_WaitForSynchro();
    /* Write to the first RTC Backup Data Register */
  RTC_WriteBackupRegister(RTC_BKP_DR0, 0x32F2);   //wu add 5 14

}
void RTC_TimeRegulate(void)
{
//  uint32_t tmp_hh = 0xFF, tmp_mm = 0xFF, tmp_ss = 0xFF;

  /***********************wu add 3 5 DATE Settings***************************************/
  RTC_DateStructure.RTC_Year  = 13;
  RTC_DateStructure.RTC_Month  = 5;
  RTC_DateStructure.RTC_Date = 4;
  RTC_DateStructure.RTC_WeekDay=6;
  if(RTC_SetDate(RTC_Format_BIN, &RTC_DateStructure) == ERROR)
  {
  }
  else
  {
    RTC_GetDate(RTC_Format_BIN, &RTC_DateStructure);
    RTC_WriteBackupRegister(RTC_BKP_DR0, 0x32F2);   //这句话很重要,不能省,不然每次烧写程序都会重新设置时间。
   
  }

  /**************************************************************************************/
  //printf("\n\r==============Time Settings=====================================\n\r");
  RTC_TimeStructure.RTC_H12     = RTC_H12_AM;
  
    RTC_TimeStructure.RTC_Hours = 11;

    RTC_TimeStructure.RTC_Minutes = 6;
  
    RTC_TimeStructure.RTC_Seconds = 0;
  
  /* Configure the RTC time register */
  if(RTC_SetTime(RTC_Format_BIN, &RTC_TimeStructure) == ERROR)
  {
//   printf("\n\r>> !! RTC Set Time failed. !! <<\n\r");
  }
  else
  {
//   printf("\n\r>> !! RTC Set Time success. !! <<\n\r");
    RTC_GetTime(RTC_Format_BIN, &RTC_TimeStructure);
    /* Indicator for the RTC configuration */
    RTC_WriteBackupRegister(RTC_BKP_DR0, 0x32F2);//给DR0赋值0x32F2,注明已经配置过,下次无需再配置
  }

使用特权

评论回复
地板
MOn51| | 2013-5-16 21:36 | 只看该作者
等看高手回复!

使用特权

评论回复
5
MOn51| | 2013-5-16 21:38 | 只看该作者
估计:
if (RTC_ReadBackupRegister(RTC_BKP_DR0) != 0x32F2)   
判早了,要先打开电源,时钟信号,允许读,才能去判断。

使用特权

评论回复
6
云仔|  楼主 | 2013-5-17 09:57 | 只看该作者
MOn51 发表于 2013-5-16 21:38
估计:
if (RTC_ReadBackupRegister(RTC_BKP_DR0) != 0x32F2)   
判早了,要先打开电源,时钟信号,允许读 ...

想问一下,RTC_TR RTC_DR这两个寄存器断电以后如果只有电池的话,寄存器里数据会保持更新么?

使用特权

评论回复
7
IJK| | 2013-5-17 10:35 | 只看该作者
云仔 发表于 2013-5-17 09:57
想问一下,RTC_TR RTC_DR这两个寄存器断电以后如果只有电池的话,寄存器里数据会保持更新么? ...

当然。否则RTC有何用?

使用特权

评论回复
8
香水城| | 2013-5-17 11:12 | 只看该作者
官网有基于STM32F4的RTC例子若干,不是一个好的起点么。
STM32F4 DSP and standard peripherals library

使用特权

评论回复
9
云仔|  楼主 | 2013-5-17 11:18 | 只看该作者
MOn51 发表于 2013-5-16 21:38
估计:
if (RTC_ReadBackupRegister(RTC_BKP_DR0) != 0x32F2)   
判早了,要先打开电源,时钟信号,允许读 ...

还有,是不是上电复位的话就会吧RTC_DR RTC_TR 寄存器里的值给复位到设定初始值呢

使用特权

评论回复
10
云仔|  楼主 | 2013-5-17 11:22 | 只看该作者
香水城 发表于 2013-5-17 11:12
官网有基于STM32F4的RTC例子若干,不是一个好的起点么。
STM32F4 DSP and standard peripherals library ...

官网上的例子我也看了,跟我的配置都差不多的,我现在怀疑是不是因为上电复位就会把RTC_DR/RTC_TR寄存器里的值复位到我配置的初始值?请问香版主如何能够使芯片上电不复位呢。不复位又怕会影响其他寄存器,纠结中。。。。。。

使用特权

评论回复
11
MOn51| | 2013-5-18 20:11 | 只看该作者
云仔 发表于 2013-5-17 11:22
官网上的例子我也看了,跟我的配置都差不多的,我现在怀疑是不是因为上电复位就会把RTC_DR/RTC_TR寄存器 ...

备份寄存器里的数据是不会因掉电冲掉的,但是控制读写的电路要正常后才能读。

使用特权

评论回复
12
hawksabre| | 2013-5-19 17:33 | 只看该作者
使用官网上的例程调试调试   这样很方便    相对来说比我们自己重新写软件方便多了   个人的一点意见   顶一个

使用特权

评论回复
13
jeckboy| | 2013-5-25 00:00 | 只看该作者
我觉得可能是你外部BAT管脚电路有问题,给它的电源可能没有做到无缝切换。一般我们这样做:VCC通过4148接到BAT,电池也通过4148接到BAT,但是在BAT管脚上你必须并联至少1个104电容或者1个104+1钽电容,这里这个电容的作用就是保证无缝切换的,没有这个电容的话,你软件上再怎么处理都解决不了

使用特权

评论回复
14
a20060341039| | 2013-12-20 13:02 | 只看该作者
来学习的

使用特权

评论回复
15
zxm19820916| | 2014-6-10 17:38 | 只看该作者
Mark!!!

使用特权

评论回复
16
dsyq| | 2019-4-15 15:01 | 只看该作者
学习!

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

1

主题

16

帖子

0

粉丝