#define DEF_BASE_YEAR 2013
#define DEF_YEAR_MAX 99
#define DEF_YEAR_MIN 0
#pragma pack(1)
typedef struct{
uint16 Year;
uint8 Month;
uint8 Day;
uint8 Hour;
uint8 Min;
uint8 Sec;
uint8 Week;
}TIMESTR;
#pragma pack()
#define RTC_CLOCK_SOURCE_LSI
//#define RTC_CLOCK_SOURCE_LSE
#define FIRST_DATA 0x32F2
__IO uint32_t AsynchPrediv = 0, SynchPrediv = 0;
RTC_InitTypeDef RTC_InitStructure;
RTC_TimeTypeDef RTC_TimeStructure;
RTC_DateTypeDef RTC_DateStructure;
void RTC_Config(void);
void RTC_AlarmConfig(void);
void RTC_WutConfig(void);
void RTC_PwConfig(void);
void MCU_RtcInit( void )
{
TIMESTR str_time;
uint8 TimeSetFlg=0;
/* Enable the PWR APB1 Clock Interface */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
/* Allow access to BKP Domain */
PWR_BackupAccessCmd(ENABLE);
if (RTC_ReadBackupRegister(RTC_BKP_DR0)!=FIRST_DATA)
{
/* RTC Configuration */
RTC_Config();
/* Write to the first RTC Backup Data Register */
RTC_WriteBackupRegister(RTC_BKP_DR0, FIRST_DATA);
}
else
{
TimeSetFlg = 1;
str_time = MCU_GetCurTime();
RTC_PwConfig();
}
RTC_AlarmConfig();
if (TimeSetFlg)
{
MCU_CurTimeSet(str_time);
}
RTC_WutConfig();
}
/**
* @brief Configure the RTC peripheral by selecting the clock source.
* @param None
* @retval None
*/
void RTC_Config(void)
{
/* Enable the PWR clock */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
/* Allow access to RTC */
PWR_BackupAccessCmd(ENABLE);
/* Reset RTC Domain */
RCC_BackupResetCmd(ENABLE);
RCC_BackupResetCmd(DISABLE);
#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 */
/* Calendar Configuration */
RTC_InitStructure.RTC_AsynchPrediv = AsynchPrediv;
RTC_InitStructure.RTC_SynchPrediv = SynchPrediv;
RTC_InitStructure.RTC_HourFormat = RTC_HourFormat_24;
RTC_Init(&RTC_InitStructure);
/* Set Current Time and Date */
//RTC_SetTime(RTC_Format_BCD, &RTC_TimeStructure);
//RTC_SetDate(RTC_Format_BCD, &RTC_DateStructure);
/* 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)
{
}
}
void RTC_PwConfig(void)
{
/* Reset RTC Domain */
RCC_BackupResetCmd(ENABLE);
RCC_BackupResetCmd(DISABLE);
RTC_WriteBackupRegister(RTC_BKP_DR0, FIRST_DATA);
#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 */
}
void RTC_AlarmConfig(void)
{
EXTI_InitTypeDef EXTI_InitStructure;
RTC_AlarmTypeDef RTC_AlarmStructure;
NVIC_InitTypeDef NVIC_InitStructure;
/* EXTI configuration */
EXTI_ClearITPendingBit(EXTI_Line17);
EXTI_InitStructure.EXTI_Line = EXTI_Line17;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
/* Enable the RTC Alarm Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = RTC_Alarm_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
/* Set the alarmA Masks */
//RTC_AlarmStructure.RTC_AlarmMask = RTC_AlarmMask_All&(~RTC_AlarmMask_Seconds);
RTC_AlarmStructure.RTC_AlarmMask = RTC_AlarmMask_All;
RTC_SetAlarm(RTC_Format_BCD, RTC_Alarm_A, &RTC_AlarmStructure);
/* Set AlarmA subseconds and enable SubSec Alarm : generate 8 interripts per Second */
RTC_AlarmSubSecondConfig(RTC_Alarm_A, 0xff, RTC_AlarmSubSecondMask_SS14_8);
/* Enable AlarmA interrupt */
RTC_ITConfig(RTC_IT_ALRA, ENABLE);
/* Enable the RTC Clock */
RCC_RTCCLKCmd(ENABLE);
/* Wait for RTC APB registers synchronisation */
RTC_WaitForSynchro();
/* Enable the alarmA */
RTC_AlarmCmd(RTC_Alarm_A, ENABLE);
}
void RTC_WutConfig(void)
{
EXTI_InitTypeDef EXTI_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
/* Enable the RTC Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = RTC_WKUP_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
/* EXTI configuration *******************************************************/
EXTI_ClearITPendingBit(EXTI_Line22);
EXTI_InitStructure.EXTI_Line = EXTI_Line22;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
/* Configure the RTC Wakeup Clock source and Counter (Wakeup event each 1 second) */
RTC_WakeUpClockConfig(RTC_WakeUpClock_RTCCLK_Div16);
RTC_SetWakeUpCounter(859);
/* Enable the Wakeup Interrupt */
RTC_ITConfig(RTC_IT_WUT, ENABLE);
/* Enable Wakeup Counter */
RTC_WakeUpCmd(ENABLE);
}
void RTC_Alarm_IRQHandler(void)
{
/* Check on the AlarmA falg and on the number of interrupts per Second (60*8) */
if(RTC_GetITStatus(RTC_IT_ALRA) != RESET)
{
/* Clear RTC AlarmA Flags */
RTC_ClearITPendingBit(RTC_IT_ALRA);
EXTI_ClearITPendingBit(EXTI_Line17);
//ExitStopMode();
}
/* Clear the EXTIL line 17 */
}
void RTC_WKUP_IRQHandler(void)
{
uint8 err;
if(RTC_GetITStatus(RTC_IT_WUT) != RESET)
{
RTC_ClearITPendingBit(RTC_IT_WUT);
EXTI_ClearITPendingBit(EXTI_Line22);
ExitStopMode();
}
}
TIMESTR MCU_GetCurTime(void)
{
TIMESTR timer;
/* Get the current Time */
RTC_GetTime(RTC_Format_BIN, &RTC_TimeStructure);
/* Get the current Date */
RTC_GetDate(RTC_Format_BIN, &RTC_DateStructure);
//timer.Year=RTC_DateStructure.RTC_Year;//得到年份
if (RTC_DateStructure.RTC_Year>DEF_YEAR_MAX)
{
timer.Year = DEF_BASE_YEAR;
}
else
{
timer.Year = RTC_DateStructure.RTC_Year + DEF_BASE_YEAR;
}
timer.Month=RTC_DateStructure.RTC_Month;//得到月份
timer.Day=RTC_DateStructure.RTC_Date; //得到日期
timer.Hour=RTC_TimeStructure.RTC_Hours; //小时
timer.Min=RTC_TimeStructure.RTC_Minutes; //分钟
timer.Sec=RTC_TimeStructure.RTC_Seconds; //秒钟
timer.Week=RTC_DateStructure.RTC_WeekDay;//获取星期
return timer;
}
BOOL MCU_CurTimeSet(TIMESTR Timer)
{
/* Set the Time */
RTC_TimeStructure.RTC_Hours = Timer.Hour;
RTC_TimeStructure.RTC_Minutes = Timer.Min;
RTC_TimeStructure.RTC_Seconds = Timer.Sec;
/* Set the Date */
if (Timer.Year<DEF_BASE_YEAR||Timer.Year>DEF_BASE_YEAR+DEF_YEAR_MAX)
{
RTC_DateStructure.RTC_Year = DEF_YEAR_MIN;
}
else
{
RTC_DateStructure.RTC_Year = Timer.Year-DEF_BASE_YEAR;
}
RTC_DateStructure.RTC_Month = Timer.Month;
RTC_DateStructure.RTC_Date = Timer.Day;
//RTC_DateStructure.RTC_Year = Timer.Year;
RTC_DateStructure.RTC_WeekDay = Timer.Week;
/* Set Current Time and Date */
RTC_SetTime(RTC_Format_BIN, &RTC_TimeStructure);
RTC_SetDate(RTC_Format_BIN, &RTC_DateStructure);
return TRUE;
}
STM32深度睡眠唤醒方式
于 2015-06-09 09:49:47 首次发布