RTC时钟采用外部32.768Khz外部晶振,RTC系统时间变量在定时器中断中每1秒更新一次( getRtc()),闹钟A中断用于芯片休眠唤醒,如果项目需求不一样,可以修改相关代码,以适应设计需求。另外,RTC的初始化时间,默认采用程序编译更新时间,原项目会在4G联网后获取网络时间,更新准确的RTC时间,也可以通过串口AT指令设置实时的RTC时间。
#ifndef __RTC_H__
#define __RTC_H__
#include "main.h"
#define UTC_LEN 10
// #define BKP_DAT1 ((uint16_t)0x0000)
// #define BKP_DAT2 ((uint16_t)0x0004)
// #define BKP_DAT3 ((uint16_t)0x0008)
// #define BKP_DAT4 ((uint16_t)0x000C)
// #define BKP_DAT5 ((uint16_t)0x0010)
// #define BKP_DAT6 ((uint16_t)0x0014)
// #define BKP_DAT7 ((uint16_t)0x0018)
// #define BKP_DAT8 ((uint16_t)0x001C)
// #define BKP_DAT9 ((uint16_t)0x0020)
// #define BKP_DAT10 ((uint16_t)0x0024)
// #define BKP_DAT11 ((uint16_t)0x0028)
// #define BKP_DAT12 ((uint16_t)0x002C)
// #define BKP_DAT13 ((uint16_t)0x0030)
// #define BKP_DAT14 ((uint16_t)0x0034)
// #define BKP_DAT15 ((uint16_t)0x0038)
// #define BKP_DAT16 ((uint16_t)0x003C)
// #define BKP_DAT17 ((uint16_t)0x0040)
// #define BKP_DAT18 ((uint16_t)0x0044)
// #define BKP_DAT19 ((uint16_t)0x0048)
// #define BKP_DAT20 ((uint16_t)0x004C)
// #define IS_BKP_DAT(DAT) \
// (((DAT) == BKP_DAT1) || ((DAT) == BKP_DAT2) || ((DAT) == BKP_DAT3) || ((DAT) == BKP_DAT4) \
// || ((DAT) == BKP_DAT5) || ((DAT) == BKP_DAT6) || ((DAT) == BKP_DAT7) || ((DAT) == BKP_DAT8) \
// || ((DAT) == BKP_DAT9) || ((DAT) == BKP_DAT10) || ((DAT) == BKP_DAT11) || ((DAT) == BKP_DAT12) \
// || ((DAT) == BKP_DAT13) || ((DAT) == BKP_DAT14) || ((DAT) == BKP_DAT15) || ((DAT) == BKP_DAT16) \
// || ((DAT) == BKP_DAT17) || ((DAT) == BKP_DAT18) || ((DAT) == BKP_DAT19) || ((DAT) == BKP_DAT20) )
#define BACKUP_REGISTER_SIZE 20
#define USER_WRITE_BKP_DAT1_DATA 0xA1A1
#define RTC_ALARM_TEST_TYPE_IRQ 0x01
#define RTC_ALARM_TEST_TYPE_OUTPUT 0x02
#define RTC_ALARM_TEST_TYPE RTC_ALARM_TEST_TYPE_IRQ
#define RTC_ALARM_OUT_TYPE_OPEN_DRAIN 0x01
#define RTC_ALARM_OUT_TYPE_PULL_PUSH 0x02
#define RTC_ALARM_OUT_TYPE RTC_ALARM_OUT_TYPE_PULL_PUSH
#define RTC_LSE_TRY_COUNT 250
typedef enum {
RTC_CLK_SRC_TYPE_HSE128=0x01,
RTC_CLK_SRC_TYPE_LSE=0x02,
RTC_CLK_SRC_TYPE_LSI=0x03,
}RTC_CLK_SRC_TYPE;
extern RTC_DateType rtcDateDefault; //RTC date default value
extern RTC_DateType rtcDate;
extern RTC_DateType rtcSetData;
extern RTC_TimeType rtcTime;
extern RTC_TimeType rtcSetTime;
extern RTC_AlarmType alarmSet;
//时区 时区范围 时区中心线
//UTC 7.5°W~7.5°E 0°
//UTC+1 7.5°E~22.5°E 15°E
//UTC+2 22.5°E~37.5°E 30°E
//UTC+3 37.5°E~52.5°E 45°E
//UTC+4 52.5°E~67.5°E 60°E
//UTC+5 67.5°E~82.5°E 75°E
//UTC+6 82.5°E~97.5°E 90°E
//UTC+7 97.5°E~112.5°E 105°E
//UTC+8 112.5°E~127.5°E 120°E
//UTC+9 127.5°E~142.5°E 135°E
//UTC+10 142.5°E~157.5°E 150°E
//UTC+11 157.5°E~172.5°E 165°E
//东西十二区 172.5°E~172.5°W 180°
//UTC-11 172.5°W~157.5°W 165°W
//UTC-10 157.5°W~142.5°W 150°W
//UTC-9 142.5°W~127.5°W 135°W
//UTC-8 127.5°W~112.5°W 120°W
//UTC-7 112.5°W~97.5°W 105°W
//UTC-6 97.5°W~82.5°W 90°W
//UTC-5 82.5°W~67.5°W 75°W
//UTC-4 67.5°W~52.5°W 60°W
//UTC-3 52.5°W~37.5°W 45°W
//UTC-2 37.5°W~22.5°W 30°W
//UTC-1 22.5°W~7.5°W 15°W
struct __RTC__
{
s8 utc; //时区
s16 offSet; //时区偏差精确到秒,32768/60/60 = 9.1小时,时区偏差正负1小时之内
s16 offsetY; //年基数,RTC年份只有后两位,所以要加上2000.
uint8_t year;
uint8_t month;
uint8_t date;
uint8_t weekDay;
uint8_t hours;
uint8_t minutes;
uint8_t seconds;
char H12; //AM:上午 PM:下午
char setTime; //时间设置
char setDate;
char utcSet;
char initialOk;
char debug;
};
extern struct __RTC__ rtc; //RTC data
extern struct __RTC__ agpsRtc;
extern struct __RTC__ resetRtc;
extern struct __RTC__ heartbeatRtc;
extern struct __RTC__ positionRepotRtc;
extern struct __RTC__ positionRepotReadyRtc;
extern struct __RTC__ sleepRtc; //工作模式中休眠时间,RTC控制变量
extern struct __RTC__ chargeRtc;
u8 weekDay(u8 year,u8 month,u8 day);
void rtcInit(void); // RTC initial
void rtcDeal(void); //RTC处理
void addSeconds(RTC_AlarmType *alarmTime,struct __RTC__ currentRtc,u32 seconds); //
void addSecondsRTC(struct __RTC__ *resultRtc,struct __RTC__ currentRtc,u32 seconds); //
void subSencondsRtc(struct __RTC__ *resultRtc,struct __RTC__ rtc,u32 seconds);
s32 subRtc(struct __RTC__ rtc1,struct __RTC__ rtc2); //return seconds = rtc1-rtc2;
void getRtc(void); //获取RTC时间
void setAarmTime(uint8_t year,uint8_t month,uint8_t day,uint8_t hours,uint8_t minutes,uint8_t seconds);
void setAlarmA(RTC_AlarmType* alarmSet); //set alarm a wake up time
#endif
#include "rtc.h"
//__DATE__ 当前日期,一个以 “MMM DD YYYY” 格式表示的字符串常量。
//__TIME__ 当前时间,一个以 “HH:MM:SS” 格式表示的字符串常量。
//__FILE__ 这会包含当前文件名,一个字符串常量。
//__LINE__ 这会包含当前行号,一个十进制常量。
//__STDC__ 当编译器以 ANSI 标准编译时,则定义为 1;判断该文件是不是标准 C 程序。
RTC_DateType rtcDateDefault; //RTC date default value
RTC_DateType rtcDate;
RTC_DateType rtcSetData;
RTC_TimeType rtcTimeDefault; //RTC time default value
RTC_TimeType rtcTime;
RTC_TimeType rtcSetTime;
RTC_AlarmType alarmSet;
struct __RTC__ rtc;
struct __RTC__ agpsRtc;
struct __RTC__ resetRtc;
struct __RTC__ heartbeatRtc;
struct __RTC__ positionRepotRtc;
struct __RTC__ positionRepotReadyRtc;
struct __RTC__ sleepRtc; //工作模式中休眠时间,RTC控制变量
struct __RTC__ chargeRtc;
RTC_InitType RTC_InitStructure;
uint32_t SynchPrediv, AsynchPrediv;
void setDefaultRtcParameter(void); //RTC default data timer
void RTC_PrescalerConfig(void)
{
/* Configure the RTC data register and RTC prescaler */
RTC_InitStructure.RTC_AsynchPrediv = AsynchPrediv;
RTC_InitStructure.RTC_SynchPrediv = SynchPrediv;
RTC_InitStructure.RTC_HourFormat = RTC_24HOUR_FORMAT;
}
ErrorStatus RTC_CLKSourceConfig(RTC_CLK_SRC_TYPE Clk_Src_Type, bool Is_First_Cfg_RCC, bool Is_Rst_Bkp)
{
uint8_t lse_ready_count=0;
ErrorStatus Status=SUCCESS;
assert_param(IS_CLKSRC_VALUE(ClkSrc));
assert_param(IS_FLCFG_VALUE(FirstLastCfg));
/* Enable the PWR clock */
RCC_EnableAPB1PeriphClk(RCC_APB1_PERIPH_PWR | RCC_APB1_PERIPH_BKP, ENABLE);
RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_AFIO, ENABLE);
/* Allow access to RTC */
PWR_BackupAccessEnable(ENABLE);
/* Reset Backup */
if (true == Is_Rst_Bkp)
{
BKP_DeInit();
}
/* Disable RTC clock */
RCC_EnableRtcClk(DISABLE);
// User_Delay_init();
if (RTC_CLK_SRC_TYPE_HSE128 == Clk_Src_Type)
{
printf("\r\n RTC_ClkSrc Is Set HSE128!\r\n");
if (true == Is_First_Cfg_RCC )
{
/* Enable HSE */
RCC_EnableLsi(DISABLE);
RCC_ConfigHse(RCC_HSE_ENABLE);
while (RCC_WaitHseStable() == ERROR)
{
}
RCC_ConfigRtcClk(RCC_RTCCLK_SRC_HSE_DIV128);
}
else
{
RCC_EnableLsi(DISABLE);
RCC_ConfigRtcClk(RCC_RTCCLK_SRC_HSE_DIV128);
/* Enable HSE */
RCC_ConfigHse(RCC_HSE_ENABLE);
while (RCC_WaitHseStable() == ERROR)
{
}
}
SynchPrediv = 0x1E8; // 8M/128 = 62.5KHz
AsynchPrediv = 0x7F; // value range: 0-7F
}
else if (RTC_CLK_SRC_TYPE_LSE == Clk_Src_Type)
{
printf("\r\n RTC_ClkSrc Is Set LSE!\r\n");
if (true == Is_First_Cfg_RCC)
{
/* Enable the LSE OSC32_IN PC14 */
RCC_EnableLsi(DISABLE); // LSI is turned off here to ensure that only one clock is turned on
#if (_TEST_LSE_BYPASS_)
RCC_ConfigLse(RCC_LSE_BYPASS);
#else
RCC_ConfigLse(RCC_LSE_ENABLE);
#endif
lse_ready_count=0;
/****Waite LSE Ready *****/
while((RCC_GetFlagStatus(RCC_FLAG_LSERD) == RESET) && (lse_ready_count<RTC_LSE_TRY_COUNT))
{
lse_ready_count++;
delay_ms(10);
/****LSE Ready failed or timeout*****/
if(lse_ready_count>=RTC_LSE_TRY_COUNT)
{
Status = ERROR;
printf("\r\n RTC_ClkSrc Set LSE Faile!\r\n");
break;
}
}
RCC_ConfigRtcClk(RCC_RTCCLK_SRC_LSE);
}
else
{
/* Enable the LSE OSC32_IN PC14 */
RCC_EnableLsi(DISABLE);
RCC_ConfigRtcClk(RCC_RTCCLK_SRC_LSE);
#if (_TEST_LSE_BYPASS_)
RCC_ConfigLse(RCC_LSE_BYPASS);
#else
RCC_ConfigLse(RCC_LSE_ENABLE);
#endif
lse_ready_count=0;
/****Waite LSE Ready *****/
while((RCC_GetFlagStatus(RCC_FLAG_LSERD) == RESET) && (lse_ready_count<RTC_LSE_TRY_COUNT))
{
lse_ready_count++;
delay_ms(10);
/****LSE Ready failed or timeout*****/
if(lse_ready_count>=RTC_LSE_TRY_COUNT)
{
Status = ERROR;
printf("\r\n RTC_ClkSrc Set LSE Faile!\r\n");
break;
}
}
}
SynchPrediv = 0xFF; // 32.768KHz
AsynchPrediv = 0x7F; // value range: 0-7F
}
else if (RTC_CLK_SRC_TYPE_LSI == Clk_Src_Type)
{
printf("\r\n RTC_ClkSrc Is Set LSI!\r\n");
if (true == Is_First_Cfg_RCC)
{
/* Enable the LSI OSC */
RCC_EnableLsi(ENABLE);
while (RCC_GetFlagStatus(RCC_FLAG_LSIRD) == RESET)
{
}
RCC_ConfigRtcClk(RCC_RTCCLK_SRC_LSI);
}
else
{
RCC_ConfigRtcClk(RCC_RTCCLK_SRC_LSI);
/* Enable the LSI OSC */
RCC_EnableLsi(ENABLE);
while (RCC_GetFlagStatus(RCC_FLAG_LSIRD) == RESET)
{
}
}
SynchPrediv = 0x136; // 39.64928KHz
AsynchPrediv = 0x7F; // value range: 0-7F
}
else
{
printf("\r\n RTC_ClkSrc Value is error!\r\n");
}
/* Enable the RTC Clock */
RCC_EnableRtcClk(ENABLE);
RTC_WaitForSynchro();
return Status;
}
// void rtcInit(void) //RTC initial
// {
// /* RTC date time alarm default value*/
// setDefaultRtcParameter();
// /* Enable the PWR clock */
// RCC_EnableAPB1PeriphClk(RCC_APB1_PERIPH_PWR| RCC_APB1_PERIPH_BKP, ENABLE);
// /* Allow access to RTC */
// PWR_BackupAccessEnable(ENABLE);
// RTC_CLKSourceConfig(RTC_CLK_SRC_TYPE_LSE, true, false);
// RTC_PrescalerConfig();
// if (USER_WRITE_BKP_DAT1_DATA != BKP_ReadBkpData(BKP_DAT1) )
// {
// /* RTC clock source select */
// if(SUCCESS==RTC_CLKSourceConfig(RTC_CLK_SRC_TYPE_LSE, true, false))
// {
// /* RTC clock source select */
// // RTC_CLKSourceConfig(RTC_CLK_SRC_TYPE_LSE, true, false);
// // RTC_PrescalerConfig();
// /* RTC date time and alarm regulate*/
// // RTC_DateRegulate();
// // RTC_TimeRegulate();
// RTC_SetDate(RTC_FORMAT_BIN, &rtcDateDefault);
// RTC_ConfigTime(RTC_FORMAT_BIN, &rtcTimeDefault);
// // RTC_AlarmRegulate(RTC_A_ALARM);
// BKP_WriteBkpData(BKP_DAT1, USER_WRITE_BKP_DAT1_DATA);
// printf("\r\n RTC Init Success\r\n");
// }
// // else
// // {
// // printf("\r\n RTC Init Faile\r\n");
// // }
// }
// getRtc(); //获取RTC时间
// /* Alarm out select option*/
// // RTC_ClrIntPendingBit(RTC_INT_ALRA);
// // EXTI18_RTCAlarm_Configuration(ENABLE);
// }
void rtcInit(void) //RTC initial
{
RTC_InitType RTC_InitStructure;
setDefaultRtcParameter(); //初始化RTC默认时间为程序烧录时间
// Enable the PWR clock
RCC_EnableAPB1PeriphClk(RCC_APB1_PERIPH_PWR | RCC_APB1_PERIPH_BKP, ENABLE);
RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_AFIO, ENABLE);
// Allow access to RTC
PWR_BackupAccessEnable(ENABLE);
// Reset Backup
// if (RstBKP == 1)
// {
// BKP_DeInit();
// }
// Disable RTC clock
RCC_EnableRtcClk(DISABLE);
// Enable the LSE OSC32_IN PC14
RCC_EnableLsi(DISABLE); //LSI is turned off here to ensure that only one clock is turned on
RCC_ConfigLse(RCC_LSE_ENABLE); //使能LSE:32.768
while (RCC_GetFlagStatus(RCC_FLAG_LSERD) == RESET) //等待LSE外部RTC时钟稳定
{
}
RCC_ConfigRtcClk(RCC_RTCCLK_SRC_LSE); //配置RTC时钟,闹钟A是能,唤醒时钟2:0 RTC/16
//Configure the RTC data register and RTC prescaler
//分频计算:32.768KHz/((AsynchPrediv+1)*(SynchPrediv+1))=32768/((0x7f+1)*(0xff+1)) = 32768/(128*256) = 1Hz
RTC_InitStructure.RTC_AsynchPrediv = 0X7F; //异步分频参数
RTC_InitStructure.RTC_SynchPrediv = 0XFF; //同步分频参数
RTC_InitStructure.RTC_HourFormat = RTC_24HOUR_FORMAT;
if (RTC_Init(&RTC_InitStructure) == ERROR)// Check on RTC init
{
}
RCC_EnableRtcClk(ENABLE);// Enable the RTC Clock
RTC_WaitForSynchro();
if (BKP_ReadBkpData(BKP_DAT1) != 0xA5A5) //第一次初始化,设置RCT date time
{
RTC_SetDate(RTC_FORMAT_BIN, &rtcDateDefault);
RTC_ConfigTime(RTC_FORMAT_BIN, &rtcTimeDefault);
BKP_WriteBkpData(BKP_DAT1, 0xA5A5); //成功配置BKP_DAT1区写 0xA5A5
}
getRtc(); //获取RTC时间
}
void EXTI17_RTCAlarm_Configuration(FunctionalState Cmd)
{
EXTI_InitType EXTI_InitStructure;
NVIC_InitType NVIC_InitStructure;
EXTI_ClrITPendBit(EXTI_LINE17);
EXTI_InitStructure.EXTI_Line = EXTI_LINE17;
#ifdef __TEST_SEVONPEND_WFE_NVIC_DIS__
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Event;
#else
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
#endif
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_InitPeripheral(&EXTI_InitStructure);
/* Enable the RTC Alarm Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = RTCAlarm_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = Cmd;
NVIC_Init(&NVIC_InitStructure);
}
void setAarmTime(uint8_t year,uint8_t month,uint8_t day,uint8_t hours,uint8_t minutes,uint8_t seconds)
{
alarmSet.DateWeekMode = RTC_ALARM_SEL_WEEKDAY_DATE; //This code just for testing.
//alarmSet.DateWeekMode = RTC_ALARM_SEL_WEEKDAY_WEEKDAY; //
if((0<day)&&(day<=31))
{
alarmSet.DateWeekValue = day;
}
else
{
alarmSet.DateWeekValue = 1;
printf("The alarm day is wrong.\r\n");
}
// alarmSet.AlarmMask = RTC_ALARMMASK_WEEKDAY | RTC_ALARMMASK_HOURS | RTC_ALARMMASK_MINUTES;
alarmSet.AlarmMask = RTC_ALARMMASK_WEEKDAY;
//alarmSet.AlarmTime.H12 = rtcTime.H12;
alarmSet.AlarmTime.Hours = hours%24;
alarmSet.AlarmTime.Minutes = minutes%60;
alarmSet.AlarmTime.Seconds = seconds%60;
}
void setAlarmA(RTC_AlarmType* alarmSet) //set alarm A wake up time
{
//setAarmTime(23,4,17,13,59,00);
RTC_EnableAlarm(RTC_A_ALARM, DISABLE); // Disable the Alarm A
if((0<alarmSet->DateWeekValue)&&(alarmSet->DateWeekValue<=31))
{
alarmSet->DateWeekValue = alarmSet->DateWeekValue;
}
else
{
alarmSet->DateWeekValue = 1;
// printf("The alarm day is wrong.");
}
RTC_SetAlarm(RTC_FORMAT_BIN, RTC_A_ALARM, alarmSet); //Configure the RTC Alarm A register
RTC_ConfigInt(RTC_INT_ALRA, ENABLE); //Enable the RTC Alarm A Interrupt
RTC_EnableAlarm(RTC_A_ALARM, ENABLE); //Enable the alarm
EXTI17_RTCAlarm_Configuration(ENABLE);
}
void RTCAlarm_IRQHandler(void)
{
if (RTC_GetITStatus(RTC_INT_ALRA) != RESET)
{
RTC_ClrIntPendingBit(RTC_INT_ALRA);
EXTI_ClrITPendBit(EXTI_LINE17);
Sleep.wakeupSource = WAKEUP_SOURCE_ALARM; //Alarm A wakeup.
IWDG_ReloadKey(); //喂狗
}
// Sleep.wakeupSource = WAKEUP_SOURCE_ALARM; //Alarm A wakeup.
}
//利用基姆拉尔森计算公式由年月日,计算出星期几。
//W= (d+2*m+3*(m+1)/5+y+y/4-y/100+y/400) mod 7
u8 weekDay(u8 year,u8 month,u8 day)
{
u8 WeekDay = 0;
WeekDay=(day+1+2*month+3*(month+1)/5+year+year/4-year/100+year/400)%7;
if(WeekDay == 0) WeekDay = 7;
return WeekDay;
}
void setDefaultRtcParameter(void) //RTC default data timer
{
u16 testYear = 0;
char data[] = __DATE__;
char time[] = __TIME__;
if(strstr(data,"Jan")!=NULL) //months
{
rtcDateDefault.Month = 1;
}
else if(strstr(data,"Feb")!=NULL) //
{
rtcDateDefault.Month = 2;
}
else if(strstr(data,"Mar")!=NULL) //
{
rtcDateDefault.Month = 3;
}
else if(strstr(data,"Apr")!=NULL) //
{
rtcDateDefault.Month = 4;
}
else if(strstr(data,"May")!=NULL) //
{
rtcDateDefault.Month = 5;
}
else if(strstr(data,"Jun")!=NULL) //
{
rtcDateDefault.Month = 6;
}
else if(strstr(data,"Jul")!=NULL) //
{
rtcDateDefault.Month = 7;
}
else if(strstr(data,"Aug")!=NULL) //
{
rtcDateDefault.Month = 8;
}
else if(strstr(data,"Sep")!=NULL) //
{
rtcDateDefault.Month = 9;
}
else if(strstr(data,"Oct")!=NULL) //
{
rtcDateDefault.Month = 10;
}
else if(strstr(data,"Nov")!=NULL) //
{
rtcDateDefault.Month = 11;
}
else if(strstr(data,"Dec")!=NULL) //
{
rtcDateDefault.Month = 12;
}
rtcDateDefault.Date = (data[4]&0x0f)*10+(data[5]&0x0f); //day
//rtcDateDefault.Year = (data[7]&0x0f)*1000+(data[8]&0x0f)*100+(data[9]&0x0f)*10+(data[10]&0x0f); //year
testYear = (data[7]&0x0f)*1000+(data[8]&0x0f)*100+(data[9]&0x0f)*10+(data[10]&0x0f); //year
if(rtc.debug) printf("testYear = %d.\r\n",testYear);
rtcDateDefault.Year = (data[9]&0x0f)*10+(data[10]&0x0f); //year 这里只能区十分位和各位计算。
rtcDateDefault.WeekDay = weekDay(rtcDateDefault.Year,rtcDateDefault.Month,rtcDateDefault.Date);
rtcTimeDefault.Hours = (time[0]&0x0f)*10+(time[1]&0x0f); //Hours
rtcTimeDefault.Minutes = (time[3]&0x0f)*10+(time[4]&0x0f); //Minutes
rtcTimeDefault.Seconds = (time[6]&0x0f)*10+(time[7]&0x0f); //Seconds
rtc.utc = 0; //默认北京时间,东八区
rtc.offSet = 0; //时差
rtc.offSet = 0; //This code just for testing.
rtc.offsetY = (data[7]&0x0f)*1000+(data[8]&0x0f)*100;
//rtc.debug = TRUE;
rtc.debug = FALSE;
}
void addSeconds(RTC_AlarmType *alarmTime,struct __RTC__ currentRtc,u32 seconds) //
{
u32 temp = 0;
u32 tempS = 0; //seconds
u32 tempM = 0; //minutes
u32 tempH = 0; //hours
u32 tempD = 0; //day
tempS = (currentRtc.seconds+seconds)%60;
tempM = (currentRtc.seconds+seconds)/60;
//newRtcTime->Seconds = tempS; //
alarmTime->AlarmTime.Seconds = tempS;
temp = (tempM+currentRtc.minutes)%60;
tempH = (tempM+currentRtc.minutes)/60;
//newRtcTime->Minutes = temp;
alarmTime->AlarmTime.Minutes = temp;
temp = (tempH+currentRtc.hours)%24;
tempD = (tempH+currentRtc.hours)/24;
//newRtcTime->Hours = temp; //确保小时不超过24
alarmTime->AlarmTime.Hours = temp; //;
alarmTime->DateWeekValue = (currentRtc.date +tempD);
alarmTime->AlarmMask = RTC_ALARMMASK_WEEKDAY;
}
void addSecondsRTC(struct __RTC__ *resultRtc,struct __RTC__ currentRtc,u32 seconds) //
{
u32 temp = 0;
u32 tempS = 0; //seconds
u32 tempM = 0; //minutes
u32 tempH = 0; //hours
u32 tempD = 0; //day
tempS = (currentRtc.seconds+seconds)%60;
tempM = (currentRtc.seconds+seconds)/60;
//newRtcTime->Seconds = tempS; //
resultRtc->seconds = tempS;
temp = (tempM+currentRtc.minutes)%60;
tempH = (tempM+currentRtc.minutes)/60;
//newRtcTime->Minutes = temp;
resultRtc->minutes = temp;
temp = (tempH+currentRtc.hours)%24;
tempD = (tempH+currentRtc.hours)/24;
//newRtcTime->Hours = temp; //确保小时不超过24
resultRtc->hours = temp; //;
resultRtc->date = (currentRtc.date +tempD);
}
void subSencondsRtc(struct __RTC__ *resultRtc,struct __RTC__ rtc,u32 seconds)
{
u32 tempValue = 0;
u32 tempHours = 0;
u32 tempMinutes = 0;
// u32 tempSeconds = 0;
tempValue = rtc.hours*60*60+rtc.minutes*60+rtc.seconds;
if(tempValue>=seconds)
{
tempValue = tempValue - seconds;
}
else
{
tempValue = 86400+tempValue-seconds;
}
resultRtc->seconds = tempValue%60;
tempMinutes = tempValue/60; //
resultRtc-> minutes = tempMinutes%60;
tempHours = tempMinutes/60;
resultRtc->hours = tempHours/24;
}
s32 subRtc(struct __RTC__ rtc1,struct __RTC__ rtc2) //return seconds = rtc1-rtc2;
{
s32 seconds = 0;
s32 tempValue1 = rtc1.hours*60*60+rtc1.minutes*60+rtc1.seconds;
s32 tempValue2 = rtc2.hours*60*60+rtc2.minutes*60+rtc2.seconds;
if(rtc1.date == rtc2.date) seconds = tempValue1 -tempValue2;
else seconds = 86400+tempValue1 -tempValue2;
// seconds = tempValue1 -tempValue2;
return seconds; //rtc1-rtc2
}
void getRtc(void) //获取RTC时间
{
RTC_GetDate(RTC_FORMAT_BIN, &rtcDate); //RTC date.
RTC_GetTime(RTC_FORMAT_BIN, &rtcTime); //RTC time.
rtc.year = rtcDate.Year;
rtc.month = rtcDate.Month;
rtc.date = rtcDate.Date;
rtc.weekDay = rtcDate.WeekDay;
rtc.hours = rtcTime.Hours;
rtc.minutes = rtcTime.Minutes;
rtc.seconds = rtcTime.Seconds;
(void)RTC->DATE; //I don't know why.
}
void rtcDeal(void) //RTC处理
{
if(rtc.setTime == 1) //Set the RTC timei
{
rtc.setTime = 0;
RTC_ConfigTime(RTC_FORMAT_BIN, &rtcSetTime);
// addSecondsRTC(&resetRtc,rtc,Parm.wkMode[Parm.currentMode].resetTime); //下次重启RTC时间
}
if(rtc.setDate == 1) //Set the RTC date.
{
rtc.setDate = 0;
RTC_SetDate(RTC_FORMAT_BIN, &rtcSetData);
}
}