注意:红色代码部分,如果不加这两句,修改时间一直卡死在RTC_WaitForLastTask()
#include "stm32f10x.h"
#include "STM32_RTC.h"
#define BKP_TIME_FLAG BKP_DR1
#define BKP_TIME_YEAR BKP_DR2
#define BKP_TIME_MONTH BKP_DR3
#define BKP_TIME_DAY BKP_DR4
#define BKP_TIME_DATE BKP_DR5
u32 Month_Days_Accu_C[13] = {0,31,59,90,120,151,181,212,243,273,304,334,365};
u32 Month_Days_Accu_L[13] = {0,31,60,91,121,152,182,213,244,274,305,335,366};
#define SecsPerDay (3600*24)
extern T_STRUCT Real_Time;//实时时间值
void RTC_Configuration(void)
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);
PWR_BackupAccessCmd(ENABLE);
BKP_DeInit();
RCC_LSEConfig(RCC_LSE_ON);
while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET)
{}
RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);
RCC_RTCCLKCmd(ENABLE);
RTC_WaitForSynchro();
RTC_WaitForLastTask();
RTC_ITConfig(RTC_IT_SEC, ENABLE);
RTC_WaitForLastTask();
RTC_SetPrescaler(32767);
RTC_WaitForLastTask();
}
void RTC_init(void)
{
if(BKP_ReadBackupRegister(BKP_TIME_FLAG) != 0xA5A5)
{
RTC_Configuration();
Real_Time.year = 2013;
Real_Time.month = 1;
Real_Time.day = 1;
Real_Time.hour = 12;
Real_Time.minute = 0;
Real_Time.second = 0;
Real_Time.date = 1;
SetRTCTime(&Real_Time);
BKP_WriteBackupRegister(BKP_TIME_FLAG, 0xA5A5);
}
else
{
if(RCC_GetFlagStatus(RCC_FLAG_PORRST) != RESET)
{
//电源复位
}
else if(RCC_GetFlagStatus(RCC_FLAG_PINRST) != RESET)
{
//External Reset occurred
}
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);
PWR_BackupAccessCmd(ENABLE);
BKP_TamperPinCmd(DISABLE);
BKP_RTCOutputConfig(BKP_RTCOutputSource_CalibClock);
RTC2Time();
}
RTC_WaitForSynchro();
RCC_ClearFlag(); //清除RCC重启标志
}
void GetRTCTime(T_STRUCT* time)
{
RTC_ITConfig(RTC_IT_SEC, DISABLE); //关闭秒中断
RTC_WaitForLastTask();
time->year=Real_Time.year;
time->month=Real_Time.month;
time->day=Real_Time.day;
time->hour=Real_Time.hour;
time->minute=Real_Time.minute;
time->second=Real_Time.second;
time->date=Real_Time.date;
RTC_WaitForLastTask();
RTC_ITConfig(RTC_IT_SEC, ENABLE); //打开秒中断
}
const u8 TAB_DATE[12]={6,2,2,5,0,3,5,1,4,6,2,4,};
u8 GetDate(T_STRUCT* time)
{
return( (time->year + time->year/4 - ( (time->month<3)&&(time->year%4==0) ) + TAB_DATE[time->month-1] + time->day )%7);
}
const u8 Month2Day_Tab[12]={31,28,31,30,31,30,31,31,30,31,30,31} ;
void RTC2Time(void)
{
u32 count;
u8 tmp,change=0;
Real_Time.year=BKP_ReadBackupRegister(BKP_TIME_YEAR);//年值
Real_Time.month=BKP_ReadBackupRegister(BKP_TIME_MONTH);//月值
Real_Time.day=BKP_ReadBackupRegister(BKP_TIME_DAY);//日值
Real_Time.date=BKP_ReadBackupRegister(BKP_TIME_DATE);//星期值
RTC_ITConfig(RTC_IT_SEC, DISABLE); //为了避免代码重入引起的问题,这里吧RTC秒中断屏蔽了
count=RTC_GetCounter();
//计算新的年月日
while (count>=0x0001517f) //上次关电到本次跨越了一天以上
{
change=1;
count-=0x0001517f;
//星期自加
if ((++Real_Time.date)>=8)
Real_Time.date=1;
//如果是2月,计算闰年(不需要考虑2099以后的400年一非润)
if (Real_Time.month==2)
{
if (Real_Time.year%4)
tmp=28;
else
tmp=29;
}
else
{
tmp=Month2Day_Tab[Real_Time.month-1];
}
if ((++Real_Time.day)>tmp)
{
Real_Time.day=1;
if ((++Real_Time.month)>12)
{
Real_Time.month=1;
if ((++Real_Time.year)>=100)
{
Real_Time.year=0;
}
}
}
//如果跨越了一天,则计算后,要存回寄存器内
if (change)
{
RTC_SetCounter(count);
BKP_WriteBackupRegister(BKP_TIME_DATE,Real_Time.date);
BKP_WriteBackupRegister(BKP_TIME_DAY,Real_Time.day);
BKP_WriteBackupRegister(BKP_TIME_MONTH,Real_Time.month);
BKP_WriteBackupRegister(BKP_TIME_YEAR,Real_Time.year);
}
}
//计算新的时分秒
Real_Time.hour=count/3600;
Real_Time.minute=(count600)/60;
Real_Time.second=(count600)`;
//重新打开RTC中断
// Check if the Power On Reset flag is set
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
PWR_BackupAccessCmd(ENABLE);
RTC_WaitForLastTask();
RTC_ITConfig(RTC_IT_SEC, ENABLE);
}
void SetRTCTime(T_STRUCT* time)
{
u32 count;
RTC_ITConfig(RTC_IT_SEC, DISABLE); //关闭秒中断
RTC_WaitForLastTask();
//付时间值到Real_Time上
Real_Time.year=time->year;
Real_Time.month=time->month;
Real_Time.day=time->day;
Real_Time.hour=time->hour;
Real_Time.minute=time->minute;
Real_Time.second=time->second;
//计算星期
time->date=Real_Time.date=GetDate(time);
//把新的年月日存到掉电寄存器上
BKP_WriteBackupRegister(BKP_TIME_DATE,Real_Time.date);
// RTC_WaitForLastTask();
BKP_WriteBackupRegister(BKP_TIME_DAY,Real_Time.day);
// RTC_WaitForLastTask();
BKP_WriteBackupRegister(BKP_TIME_MONTH,Real_Time.month);
// RTC_WaitForLastTask();
BKP_WriteBackupRegister(BKP_TIME_YEAR,Real_Time.year);
// RTC_WaitForLastTask();
//计算新的RTC count值
count=Real_Time.hour*3600+Real_Time.minute*60+Real_Time.second;
RTC_WaitForLastTask();
RTC_SetCounter(count);
// Check if the Power On Reset flag is set
//注意红色代码部分,如果不加这两句,修改时间一直卡死在 RTC_WaitForLastTask()
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
PWR_BackupAccessCmd(ENABLE);
RTC_WaitForLastTask();
RTC_ITConfig(RTC_IT_SEC, ENABLE); //打开秒中断
}
void RTCTick(void)
{
u8 tmp;
if ((++Real_Time.second)>59)
{
Real_Time.second=0;
if ((++Real_Time.minute)>59)
{
Real_Time.minute=0;
if ((++Real_Time.hour)>23)
{
Real_Time.hour=0;
//星期自加
if ((++Real_Time.date)>=8)
Real_Time.date=1;
//--存储新的星期
BKP_WriteBackupRegister(BKP_DR5,Real_Time.date);
//如果是2月,计算闰年(不需要考虑2099以后的400年一非润)
if (Real_Time.month==2)
{
if (Real_Time.year%4)
tmp=28;
else
tmp=29;
}
else
{
tmp=Month2Day_Tab[Real_Time.month-1];
}
if ((++Real_Time.day)>tmp)
{
Real_Time.day=1;
if ((++Real_Time.month)>12)
{
Real_Time.month=1;
if ((++Real_Time.year)>99)
{
Real_Time.year=0;
}
//--储存新的年
BKP_WriteBackupRegister(BKP_DR2,Real_Time.year);
}
//--储存新的月
BKP_WriteBackupRegister(BKP_DR3,Real_Time.month);
}
//--储存新的日
BKP_WriteBackupRegister(BKP_DR4,Real_Time.day);
}
}
}
}