打印

请教: STM32F051R8T6的RTC掉电不能保存的问题

[复制链接]
9168|18
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
suzhwt|  楼主 | 2013-1-10 13:22 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
这两天在学F051的RTC,电路板上装了扣式电池,但是在电路板下电后再上电,时间与日期不能保存,请问:
这个芯片本来就不能在电路板下电后使用板载扣式电池保持走时吗?

使用的是外部32.768KHz的晶振,上电后能正常走时.

先行谢过.
沙发
airwill| | 2013-1-10 15:18 | 只看该作者
根据数据手册, 这个功能应该是不会有问题的. 恐怕是你的软硬件有缺陷吧

使用特权

评论回复
板凳
uet_cache| | 2013-1-10 15:34 | 只看该作者
芯片一般不会出错,,最好有问题先检查自己的程序和硬件。。

使用特权

评论回复
地板
suzhwt|  楼主 | 2013-1-10 16:21 | 只看该作者
在坛里翻了一下以贴子,在外振上加了2个电容,解决了起振难的问题;同时按照香主的意见,把VCC至VBAT的二极管去掉了,硬件如下图:


代码部分如下:
#include "Includes.h"
#include "Constants.h"
#include "Functions.h"
#include "Globals.h"

#define RTC_BKP_VALUE         0xA5A5

/*****************************************************************
@Fn: ConfigRTC()
@Br: 配置RTC   
@Pa: 无  
@Rt: 无
@Sp: 无
*****************************************************************/
void ConfigRTC( void ){
  RCC_APB1PeriphClockCmd( RCC_APB1Periph_PWR, ENABLE );     /* Enable the PWR clock */  
  PWR_BackupAccessCmd( ENABLE );                            /* Allow access to RTC */
  
  if( RTC_ReadBackupRegister( RTC_BKP_DR0 ) != RTC_BKP_VALUE )
    {
    RTC_InitTypeDef RTC_InitStructure;

    RCC_LSEConfig( RCC_LSE_ON );    /* Enable the LSE OSC */
    while( RCC_GetFlagStatus( RCC_FLAG_LSERDY ) == RESET );   /* Wait till LSE is ready */  
   
    RCC_RTCCLKConfig( RCC_RTCCLKSource_LSE );   /* Select the RTC Clock Source */
   
    RCC_RTCCLKCmd( ENABLE );        /* Enable the RTC Clock */
    RTC_WaitForSynchro();           /* Wait for RTC APB registers synchronisation */
   
    RTC_InitStructure.RTC_AsynchPrediv = 127;
    RTC_InitStructure.RTC_SynchPrediv = 255;
    RTC_InitStructure.RTC_HourFormat = RTC_HourFormat_24;
    if( RTC_Init( &RTC_InitStructure ) == ERROR )
      {
      /* 此处作设置失败处理 */   
      }
   
    ConfigCalendarTime( 13, 1, 10 );
    }
  else
    {
//    RCC_APB1PeriphClockCmd( RCC_APB1Periph_PWR, ENABLE );   /* Enable the PWR clock */
//    PWR_BackupAccessCmd( ENABLE );                          /* Allow access to RTC */
    RTC_WaitForSynchro();                   /* Wait for RTC APB registers synchronisation */
    RTC_ClearFlag( RTC_FLAG_ALRAF );        /* Clear the RTC Alarm Flag */
    }
}
/*****************************************************************
@Fn: ConfigCalendarTime()
@Br: 配置日历时间   
@Pa: 时,分,秒   
@Rt: 无
@Sp: 无
*****************************************************************/
void ConfigCalendarTime( uchar Hr, uchar Min, uchar Sec ){
  RTC_TimeTypeDef RTC_TimeStructure;
  
  RTC_TimeStructure.RTC_H12 = RTC_H12_AM;
  RTC_TimeStructure.RTC_Hours = Hr;
  RTC_TimeStructure.RTC_Minutes = Min;
  RTC_TimeStructure.RTC_Seconds = Sec;
  if( RTC_SetTime( RTC_Format_BIN, &RTC_TimeStructure ) == ERROR )
    {
    /* 此处作设置失败处理 */  
    }
  else
    RTC_WriteBackupRegister( RTC_BKP_DR0, RTC_BKP_VALUE );  /* Indicator for the RTC configuration */
}
/*****************************************************************
@Fn: ConfigCalendarDate()
@Br: 配置日历日期   
@Pa: 周,年,月,日   
@Rt: 无
@Sp: 无
*****************************************************************/
void ConfigCalendarDate( uchar Week, uchar Yr, uchar Mont, uchar Day ){
  RTC_DateTypeDef RTC_DateStructure;
  
  RTC_DateStructure.RTC_WeekDay = Week;
  RTC_DateStructure.RTC_Year = Yr;
  RTC_DateStructure.RTC_Month = Mont;
  RTC_DateStructure.RTC_Date = Day;
  if( RTC_SetDate( RTC_Format_BIN, & RTC_DateStructure ) == ERROR )
    {
    /* 此处作设置失败处理 */
    }
}
/*****************************************************************
@Fn: ConfigRTC_Alarm()
@Br: 配置RTC报警   
@Pa: 时,分,秒   
@Rt: 无
@Sp: 无
*****************************************************************/
void ConfigRTC_Alarm( uchar Hr, uchar Min, uchar Sec ){
  RTC_AlarmTypeDef RTC_AlarmStructure;
  
  RTC_AlarmCmd( RTC_Alarm_A, DISABLE );     /* Disable the Alarm A */
  RTC_AlarmStructure.RTC_AlarmTime.RTC_H12 = RTC_H12_AM;
  RTC_AlarmStructure.RTC_AlarmTime.RTC_Hours = Hr;
  RTC_AlarmStructure.RTC_AlarmTime.RTC_Minutes = Min;
  RTC_AlarmStructure.RTC_AlarmTime.RTC_Seconds = Sec;
  
  /* Set the Alarm A */
  RTC_AlarmStructure.RTC_AlarmDateWeekDay = 0x31;
  RTC_AlarmStructure.RTC_AlarmDateWeekDaySel = RTC_AlarmDateWeekDaySel_Date;
  RTC_AlarmStructure.RTC_AlarmMask = RTC_AlarmMask_DateWeekDay;
  
  RTC_SetAlarm( RTC_Format_BIN, RTC_Alarm_A, &RTC_AlarmStructure ); /* Configure the RTC Alarm A register */
  
  RTC_ITConfig( RTC_IT_ALRA, ENABLE );    /* Enable the RTC Alarm A Interrupt */
  
  RTC_AlarmCmd( RTC_Alarm_A, ENABLE );    /* Enable the alarm  A */
}
/*****************************************************************
@Fn: ConfigRTC_Interrupt()
@Br: 配置RTC中断   
@Pa: 无  
@Rt: 无
@Sp: 无
*****************************************************************/
void ConfigRTC_Interrupt( void ){
  NVIC_InitTypeDef  NVIC_InitStructure;
  
  NVIC_InitStructure.NVIC_IRQChannel = RTC_IRQn;    /* Enable the RTC Alarm Interrupt */
  NVIC_InitStructure.NVIC_IRQChannelPriority = 3;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init( &NVIC_InitStructure );
}
/*****************************************************************
@Fn: GetRTC_Time()
@Br: 读取日历时间   
@Pa: 时,分,秒   
@Rt: 无
@Sp: 无
*****************************************************************/
void GetRTC_Time( uchar *Hr, uchar *Min, uchar *Sec ){
  RTC_TimeTypeDef RTC_TimeStructure;
  
  RTC_GetTime( RTC_Format_BIN, &RTC_TimeStructure );
  *Hr = RTC_TimeStructure.RTC_Hours;
  *Min = RTC_TimeStructure.RTC_Minutes;
  *Sec = RTC_TimeStructure.RTC_Seconds;
}
/*****************************************************************
@Fn: GetCalendarDate()
@Br: 读取日历日期   
@Pa: 周,年,月,日   
@Rt: 无
@Sp: 无
*****************************************************************/
void GetCalendarDate( uchar *Week, uchar *Yr, uchar *Mont, uchar *Day ){
  RTC_DateTypeDef RTC_DateStructure;

  RTC_GetDate( RTC_Format_BIN, &RTC_DateStructure );
  *Week = RTC_DateStructure.RTC_WeekDay;
  *Yr = RTC_DateStructure.RTC_Year;
  *Mont = RTC_DateStructure.RTC_Month;
  *Day = RTC_DateStructure.RTC_Date;
}
/*****************************************************************
@Fn: GetRTC_Alarm()
@Br: 读取日历报警时间值   
@Pa: 时,分,秒   
@Rt: 无
@Sp: 无
*****************************************************************/
void GetRTC_Alarm( uchar *Hr, uchar *Min, uchar *Sec ){
  RTC_AlarmTypeDef  RTC_AlarmStructure;
  
  RTC_GetAlarm( RTC_Format_BIN, RTC_Alarm_A, &RTC_AlarmStructure );
  *Hr = RTC_AlarmStructure.RTC_AlarmTime.RTC_Hours;
  *Min = RTC_AlarmStructure.RTC_AlarmTime.RTC_Minutes;
  *Sec = RTC_AlarmStructure.RTC_AlarmTime.RTC_Seconds;
}   
  
void RTC_IRQHandler( void ){
  if( RTC_GetITStatus( RTC_IT_ALRA ) != RESET )
    {
   
    RTC_ClearITPendingBit( RTC_IT_ALRA );
    }
}  
  
  
  
  
  

未命名.GIF (45.26 KB )

硬件图

硬件图

使用特权

评论回复
5
suzhwt|  楼主 | 2013-1-10 16:22 | 只看该作者
搞了2天了,走进死胡同了,哪位仁兄指点一下吧.
谢谢.

使用特权

评论回复
6
zhaoyu2005| | 2013-1-10 16:44 | 只看该作者

RCC_APB1PeriphClockCmd( RCC_APB1Periph_PWR, ENABLE );     /* Enable the PWR clock */  
改成
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);
试试,严重怀疑是你的数据没正确写入造成的
在执行完 RTC_WriteBackupRegister( RTC_BKP_DR0, RTC_BKP_VALUE );  看下数据是不是0xA5A5

使用特权

评论回复
7
suzhwt|  楼主 | 2013-1-10 16:54 | 只看该作者
感谢zhaoyu2005仁兄:
我这是M0的片子,没有"RCC_APB1Periph_BKP"这个时钟项.

在执行完"RTC_WriteBackupRegister( RTC_BKP_DR0, RTC_BKP_VALUE ); ", 从寄存器里看到的数据就是0xA5A5.
下电后再上电,就变成"0"了.

搞不明白是哪里错了.

使用特权

评论回复
8
zhaoyu2005| | 2013-1-11 09:04 | 只看该作者
不好意思,看错了,还以为是105呢,如果断电再上电,确认由A5A5变成0,那估计是后备电池供电有问题,或者是防入侵那个引脚(M3是PA0)出现了触发电平,并且防入侵功能启用了,造成数据被擦除。
总之不会是大问题,仔细检查下,再看下例程

使用特权

评论回复
9
suzhwt|  楼主 | 2013-1-12 09:47 | 只看该作者
并且,还有一个现象,那就是,使用JTAG复位芯片后,再看REG里的数据,同样也变成了"0".

使用特权

评论回复
10
wgsxsm| | 2013-4-23 16:52 | 只看该作者
马克,最近准备用F0的RTC,如果通过就用,通不过的话就换成PCF8563

使用特权

评论回复
11
wgsxsm| | 2013-4-23 23:30 | 只看该作者
楼主应该是设置完时间后没有写入BackupRegister造成的

使用特权

评论回复
12
rockt818| | 2014-1-16 17:32 | 只看该作者
我想做RTC报警,可无法产生中断啊

使用特权

评论回复
13
wangyue3804| | 2014-6-13 13:54 | 只看该作者
您好:您这M0的RTC掉电不保存的问题解决好了吗?能不能把程序给我传一下啊,小弟最近也在搞这个,使用LSE做时钟,希望掉电后时间会继续走,跟实际的一样,能不能帮个忙啊

使用特权

评论回复
14
火之泪| | 2014-11-25 12:56 | 只看该作者
RTC报警如何产生中断

使用特权

评论回复
15
Cheribat| | 2014-12-9 11:14 | 只看该作者
我也要用这个RTC了

使用特权

评论回复
16
Cheribat| | 2014-12-9 15:06 | 只看该作者
看了一下F0的库  前面的BKP_VALUE是0X32F0 所以应该是这个地方有问题

使用特权

评论回复
17
snyanglq| | 2015-1-19 11:20 | 只看该作者
楼主,问题解决了吗?分享下吧,我的问题也是一样,重新上电就为零了,要重新进行设置,不过我设定的是0x32F0不是0xA5A5

使用特权

评论回复
18
oldpower| | 2015-6-24 20:33 | 只看该作者
谢谢,我也试试这段代码

使用特权

评论回复
19
尤彼卡| | 2015-6-24 22:00 | 只看该作者
不知道楼主搞定了吗

使用特权

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

本版积分规则

7

主题

73

帖子

1

粉丝