OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 14250|回复: 2

关于stm32断电后时间不能保存的问题

[复制链接]

16

主题

34

帖子

0

精华

初级会员

Rank: 2

积分
118
金钱
118
注册时间
2011-1-27
在线时间
0 小时
发表于 2012-5-17 10:51:51 | 显示全部楼层 |阅读模式

问题现象:
我用的芯片是stm32F103VCT6,在VBAT脚加了3.3V电池,断电后,该引脚确实有电压
但是断电后,再上电,时间从新开始了,不能记录我之前修改好的

我看了一下寄存器,RTC_CNTH这个里面是用来存放断点之前的时钟数据的,但是断电之后再上电,这个里面的数据都没有了
但是软件复位就可以,依然有记录。
这是怎么回事呢?

void RTC_Configuration(void)
{
      /* Enable PWR and BKP clocks */
      RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);
   
      /* Allow access to BKP Domain */
      PWR_BackupAccessCmd(ENABLE);
   
      /* Reset Backup Domain */
      BKP_DeInit();
   
      /* Enable LSE */
      RCC_LSEConfig(RCC_LSE_ON);
      /* Wait till LSE is ready */
      while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET)
      {}
   
      /* Select LSE as RTC Clock Source */
      RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);
   
      /* Enable RTC Clock */
      RCC_RTCCLKCmd(ENABLE);
   
      /* Wait for RTC registers synchronization */
      RTC_WaitForSynchro();
     
      /* Wait until last write operation on RTC registers has finished */
      RTC_WaitForLastTask();
   
      /* Enable the RTC Second */
     // RTC_ITConfig(RTC_IT_SEC, ENABLE);
   
      /* Wait until last write operation on RTC registers has finished */
     // RTC_WaitForLastTask();
   
      /* Set RTC prescaler: set RTC period to 1sec */
      RTC_SetPrescaler(32767); /* RTC period = RTCCLK/RTC_PR = (32.768 KHz)/(32767+1) */
   
      /* Wait until last write operation on RTC registers has finished */
      RTC_WaitForLastTask();

}

void RTC_Config(void)
{
     //lzf 2011.12.7 下面三句用来对BKP寄存器清0,缺一不可,只供实验用
      //RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);
   
      //Allow access to BKP Domain
      //PWR_BackupAccessCmd(ENABLE);
      //BKP_WriteBackupRegister(BKP_DR1, 0x0);
      //BKP_WriteBackupRegister(BKP_DR1, 0x0);
      //Reset Backup Domain
      //2011.12.7 
 
     if (BKP_ReadBackupRegister(BKP_DR1) != 0xA5A5 )
      {
           //Backup data register value is not correct or not yet programmed (when the first time the program is executed)
       
          //  g_bNVRamBl=0;     //电池电压低
            //RTC Configuration
            RTC_Configuration();
           
            Os_InitTime();    //修改系统时间
                
            BKP_WriteBackupRegister(BKP_DR1, 0xA5A5);
      }
      else
      {
           // g_bNVRamBl=1;    //电池电压正常
            //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 PWR and BKP clocks
            RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);
         
            //Allow access to BKP Domain
            PWR_BackupAccessCmd(ENABLE);
           
            Os_InitTime();
           
            RTC_WaitForLastTask();
       }
     
#ifdef RTCClockOutput_Enable 
  //Enable PWR and BKP clocks
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);
 
  //Allow access to BKP Domain
  PWR_BackupAccessCmd(ENABLE);
 
  //Disable the Tamper Pin
  BKP_TamperPinCmd(DISABLE); //To output RTCCLK/64 on Tamper pin, the tamper
                              //functionality must be disabled
                              
  //Enable RTC Clock Output on Tamper Pin
  BKP_RTCOutputConfig(BKP_RTCOutputSource_CalibClock);
#endif

  //Clear reset flags
  RCC_ClearFlag();

}

void Os_SetTime(TIME_S7* Time)
{
    #if OS_CRITICAL_METHOD == 3                                   /* Storage for CPU status register       */
    OS_CPU_SR  cpu_sr = 0;
    #endif

    u32  TimValue,IsLeap,i,DateNum=0;

    OS_ENTER_CRITICAL();

    sSysTime.Year = Time->Year;
    sSysTime.Month = Time->Month;
    sSysTime.Date = Time->Date;
    sSysTime.Hour = Time->Hour;
    sSysTime.Minute = Time->Minute;
    sSysTime.Second = Time->Second;
    sSysTime.MillSec = Time->MillSec;

    IsLeap = IsLeapYear(&sSysTime);

    if(IsLeap==0)
    {
        for(i=0;i<Time->Month;i++)
        {
      DateNum = DateNum + EachMonth[IsLeap];
        }
        TimValue=(sSysTime.Year-Ymark)*31536000+(DateNum+sSysTime.Date)*86400+sSysTime.Hour*3600
                                              + sSysTime.Minute*60 + sSysTime.Second+sSysTime.MillSec/1000;
    }
    else
    {

        for(i=0;i<Time->Month;i++)
        {
      DateNum = DateNum + EachMonth[IsLeap];
        }
         /*  the value to store in RTC counter register */
        TimValue=(sSysTime.Year-Ymark)*31622400+(DateNum+sSysTime.Date)*86400+sSysTime.Hour*3600
                                              + sSysTime.Minute*60 + sSysTime.Second+sSysTime.MillSec/1000;

    }

    /* Enable PWR and BKP clocks */
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);

    /* Allow access to BKP Domain */
    PWR_BackupAccessCmd(ENABLE);

    /* Change the current time */
    RTC_SetCounter(TimValue);

    /* Wait until last write operation on RTC registers has finished */
    RTC_WaitForLastTask();

 //   RTC_T_NUM = RTC_GetCounter();

 //   RTC_WaitForLastTask();

    OS_EXIT_CRITICAL();
}

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165371
金钱
165371
注册时间
2010-12-1
在线时间
2110 小时
发表于 2012-5-17 14:38:14 | 显示全部楼层
移植我们的代码看看。我的那个RTC代码。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

16

主题

34

帖子

0

精华

初级会员

Rank: 2

积分
118
金钱
118
注册时间
2011-1-27
在线时间
0 小时
 楼主| 发表于 2012-5-17 15:03:55 | 显示全部楼层
我一会试试
回复 支持 反对

使用道具 举报

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

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-2-25 23:21

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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