#include "stm32f0xx.h"
#include "hardware.h"
#define BKP_VALUE 0x55AA
#define BKP_ADDRESS 0x0004
#define RTC_CLOCK_SOURCE_LSE /* LSE used as RTC source clock */
volatile uint32_t AsynchPrediv = 0, SynchPrediv = 0;
unsigned char RTC_String[20] = "2012-09-28 12:00:00";
unsigned char RTC_STime[10];
unsigned char RTC_SDate[10];
RTC_TimeTypeDef RTC_Time;
RTC_DateTypeDef RTC_Date;
void RTC_Config(void)
{
/* Enable the PWR clock */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
/* 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 = 0x18F;
AsynchPrediv = 0x63;
#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();
}
void RTC_TimeRegulate(void)
{
RTC_Date.RTC_Year = 12;
RTC_Date.RTC_Month = 10;
RTC_Date.RTC_Date = 5;
RTC_Date.RTC_WeekDay = 5;
RTC_SetDate(RTC_Format_BIN, &RTC_Date);
RTC_Time.RTC_Hours = 12;
RTC_Time.RTC_Minutes = 0;
RTC_Time.RTC_Seconds = 0;
/* Configure the RTC time register */
if(RTC_SetTime(RTC_Format_BIN, &RTC_Time) == ERROR)
{
LCD_WR_String("RTC Set Time failed. !!");
}
else
{
LCD_WR_String("RTC Set Time success. !!");
/* Indicator for the RTC configuration */
RTC_WriteBackupRegister(RTC_BKP_DR0, BKP_VALUE);
RTC_WriteBackupRegister(RTC_BKP_DR1, BKP_ADDRESS);
}
}
void RTC_Configuration(void)
{
RTC_InitTypeDef RTC_InitStructure;
if (RTC_ReadBackupRegister(RTC_BKP_DR0) != BKP_VALUE)
{
/* 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;
/* Check on RTC init */
if (RTC_Init(&RTC_InitStructure) == ERROR)
{
LCD_WR_String("RTC Prescaler Config failed.");
}
/* Configure the time register */
RTC_TimeRegulate();
}
else
{
/* Check if the Power On Reset flag is set */
if (RCC_GetFlagStatus(RCC_FLAG_PORRST) != RESET)
{
LCD_WR_String("Power On Reset occurred....");
}
/* Check if the Pin Reset flag is set */
else if (RCC_GetFlagStatus(RCC_FLAG_PINRST) != RESET)
{
LCD_WR_String("External Reset occurred....");
}
LCD_WR_String("No need to configure RTC....");
/* Enable the PWR clock */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
/* Allow access to RTC */
PWR_BackupAccessCmd(ENABLE);
/* Wait for RTC APB registers synchronisation */
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);
/* Display the RTC Time and Alarm */
RTC_GetTime(RTC_Format_BIN, &RTC_Time);
RTC_GetDate(RTC_Format_BIN, &RTC_Date);
}
USART1_Address = RTC_ReadBackupRegister(RTC_BKP_DR1);
RTC_Update();
}
void RTC_Update(void)
{
unsigned int tmpreg;
unsigned int i;
tmpreg = (uint32_t)(RTC->DR & 0x00FFFF3F);
RTC_String[ 0] = '2';
RTC_String[ 1] = '0';
RTC_String[ 2] = '0' + (unsigned char)((tmpreg & RTC_DR_YT) >> 20);
RTC_String[ 3] = '0' + (unsigned char)((tmpreg & RTC_DR_YU) >> 16);
RTC_String[ 5] = '0' + (unsigned char)((tmpreg & RTC_DR_MT) >> 12);
RTC_String[ 6] = '0' + (unsigned char)((tmpreg & RTC_DR_MU) >> 8);
RTC_String[ 8] = '0' + (unsigned char)((tmpreg & RTC_DR_DT) >> 4);
RTC_String[ 9] = '0' + (unsigned char)((tmpreg & RTC_DR_DU) >> 0);
tmpreg = (uint32_t)(RTC->TR & 0x007F7F7F);
RTC_String[11] = '0' + (unsigned char)((tmpreg & RTC_TR_HT) >> 20);
RTC_String[12] = '0' + (unsigned char)((tmpreg & RTC_TR_HU) >> 16);
RTC_String[14] = '0' + (unsigned char)((tmpreg & RTC_TR_MNT) >> 12);
RTC_String[15] = '0' + (unsigned char)((tmpreg & RTC_TR_MNU) >> 8);
RTC_String[17] = '0' + (unsigned char)((tmpreg & RTC_TR_ST) >> 4);
RTC_String[18] = '0' + (unsigned char)((tmpreg & RTC_TR_SU) >> 0);
for (i = 0; i < 8; i++) RTC_STime[i] = RTC_String[11 + i];
for (i = 0; i < 8; i++) RTC_SDate[i] = RTC_String[ 2 + i];
}
unsigned char RTC_GetWeek(unsigned short year, unsigned char month, unsigned char day)
{
unsigned char const table_week[12] = {0, 3, 3, 6, 1, 4, 6, 2, 5, 0, 3, 5};
unsigned char yearH, yearL;
unsigned short temp;
yearH = year / 100;
yearL = year % 100;
// 如果为21世纪,年份数加100
if (yearH > 19) yearL += 100;
// 所过闰年数只算1900年之后的
temp = yearL + yearL / 4;
temp = temp % 7;
temp = temp + day + table_week[month - 1];
if (yearL % 4 == 0 && month < 3) temp--;
return(temp % 7);
}
void RTC_SaveDate(unsigned char *pStr)
{
RTC_DateTypeDef RTC_Setup;
if (pStr[2] == '-' && pStr[5] == '-' &&
pStr[0] >= '0' && pStr[0] <= '9' && pStr[1] >= '0' && pStr[1] <= '9' &&
pStr[3] >= '0' && pStr[3] <= '9' && pStr[4] >= '0' && pStr[1] <= '9' &&
pStr[6] >= '0' && pStr[6] <= '9' && pStr[7] >= '0' && pStr[1] <= '9')
{
RTC_Setup.RTC_Year = (pStr[0] - '0') * 10 + (pStr[1] - '0');
RTC_Setup.RTC_Month = (pStr[3] - '0') * 10 + (pStr[4] - '0');
RTC_Setup.RTC_Date = (pStr[6] - '0') * 10 + (pStr[7] - '0');
RTC_Setup.RTC_WeekDay = RTC_GetWeek(RTC_Setup.RTC_Year + 2000, RTC_Setup.RTC_Month, RTC_Setup.RTC_Date);
RTC_SetDate(RTC_Format_BIN, &RTC_Setup);
}
}
void RTC_SaveTime(unsigned char *pStr)
{
RTC_TimeTypeDef RTC_Setup;
if (pStr[2] == ':' && pStr[5] == ':' &&
pStr[0] >= '0' && pStr[0] <= '9' && pStr[1] >= '0' && pStr[1] <= '9' &&
pStr[3] >= '0' && pStr[3] <= '9' && pStr[4] >= '0' && pStr[1] <= '9' &&
pStr[6] >= '0' && pStr[6] <= '9' && pStr[7] >= '0' && pStr[1] <= '9')
{
RTC_Setup.RTC_Hours = (pStr[0] - '0') * 10 + (pStr[1] - '0');
RTC_Setup.RTC_Minutes = (pStr[3] - '0') * 10 + (pStr[4] - '0');
RTC_Setup.RTC_Seconds = (pStr[6] - '0') * 10 + (pStr[7] - '0');
RTC_Setup.RTC_H12 = 0x00;
RTC_SetTime(RTC_Format_BIN, &RTC_Setup);
}
}