Files
HBshuiwuConcentrator/APP/Rtc.c
2025-12-15 16:07:49 +08:00

224 lines
5.7 KiB
C

/**
******************************************************************************
* @file hal_timer.c
* @author William Liang
* @version V1.0.0
* @date 07/18/2013
* @brief This file contains the initialization and handle of the timer.
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "Rtc.h"
#include "uart.h"
#include "Mem.h"
#include "Led.h"
/** @addtogroup Timer
* @{
*/
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
static const u8 daysInMonth[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
u32 g_SystickCounter = 0;
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
/**
* @brief Initialize the RTC.
* @param None.
* @retval None.
*/
void RTC_Init(void)
{
/* Enable PWR and BKP clocks */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);
/* Allow access to BKP Domain */
PWR_BackupAccessCmd(ENABLE);
/* Select HSE as RTC Clock Source */
RCC_RTCCLKConfig(RCC_RTCCLKSource_HSE_Div128);
//BKP_DeInit();
if (BKP_ReadBackupRegister(RTC_VALID_REG) != RTC_VALID_FLAG)
{
/* Enable RTC Clock */
RCC_RTCCLKCmd(ENABLE);
//RCC_RTCCLKConfig(RCC_RTCCLKSource_HSE_Div128);
/* Wait for RTC registers synchronization */
RTC_WaitForSynchro();
/* Wait until last write operation on RTC registers has finished */
RTC_WaitForLastTask();
/* Set RTC prescaler: set RTC period to 1sec */
RTC_SetPrescaler(RTC_PRESCALER); /* RTC period = RTCCLK/RTC_PR = (8 MHz /128)/(RTC_PRESCALER+1) */
/* Wait until last write operation on RTC registers has finished */
RTC_WaitForLastTask();
/* Set RTC Valid Flag in the BKP */
BKP_WriteBackupRegister(RTC_VALID_REG, RTC_VALID_FLAG);
/* Initialize current time to 2010/1/1 00:00:00 */
Time_Set(17, 8, 17, 8, 23, 42);
}
else
{
/* Wait for RTC registers synchronization */
RTC_WaitForSynchro();
}
}
/**
* @brief convert current time format from the total seconds since 2010 to the time struct.
* @param utcTime: input variable, total seconds since 2010.
* @retval time: the struct of current time.
*/
sTime TimetoBCD(u32 utcTime)
{
sTime time;
u32 secondsSince2010 = (utcTime - START_OF_2010);
u16 daysSince2010 = (secondsSince2010 >> 2) / (u16)(SECS_IN_DAY >> 2);
u32 secondInDay = secondsSince2010 - ((u32)daysSince2010) * SECS_IN_DAY;
u8 yearsSince2000 = 0;
u16 daysRemaining = daysSince2010;
u16 accum = 10;//We start from 2010
u8 phase;
for (phase = 0; phase < 2; phase++)
{
while (1)
{
u16 tick;
if (phase == 0)
{
tick = ((accum & 0x03) == 0 ? 366 : 365);
}
else
{
tick = daysInMonth[accum];
if ((accum == 1) && ((yearsSince2000 & 0x03) == 0))
{
tick++;
}
}
if (tick <= daysRemaining)
{
daysRemaining -= tick;
accum++;
}
else
{
if (phase == 0)
{
yearsSince2000 = accum;
accum = 0;
}
break;
}
}
}
time.year = yearsSince2000;
time.month = accum + 1;
time.day = daysRemaining + 1;
time.hour = secondInDay / 3600;
time.minute = (secondInDay - time.hour * 3600) / 60;
time.second = (secondInDay - time.hour * 3600) % 60;
return time;
}
/**
* @brief Set the current time.
* @param year: input variable, the year of current time.
* @param month: input variable, the month of current time.
* @param day: input variable, the day of current time.
* @param hour: input variable, the hour of current time.
* @param min: input variable, the minute of current time.
* @param sec: input variable, the second of current time.
* @retval None.
*/
void Time_Set(u8 year, u8 month, u8 day, u8 hour, u8 min, u8 sec)
{
u32 secs = START_OF_2010 + (u32) hour * 3600 + (u32) min * 60 + (u32) sec;
u16 days = day - 1;
u8 i;
//printf("设置系统时间 %02d-%02d-%02d %02d:%02d:%02d\r\n", year, month, day, hour, min, sec);
for (i = 10; i < year; i++)
{
days += 365;
if ((i & 0x03) == 0)
{
days++;
}
}
for (i = 0; i < month - 1; i++)
{
days += daysInMonth[i];
}
if ((month > 2) && ((year & 0x03) == 0))
{
days++;
}
secs += ((u32) days) * SECS_IN_DAY;
/* Wait until last write operation on RTC registers has finished */
RTC_WaitForLastTask();
/* Change the current time */
RTC_SetCounter(secs);
/* Wait until last write operation on RTC registers has finished */
RTC_WaitForLastTask();
}
/**
* @brief Print the current time.
* @param None.
* @retval None.
*/
void Time_Get(void)
{
sTime CurrentTime;
CurrentTime = TimetoBCD(RTC_GetCounter());
printf("获取系统时间 %02d-%02d-%02d %02d:%02d:%02d %d\r\n",
CurrentTime.year,
CurrentTime.month,
CurrentTime.day,
CurrentTime.hour,
CurrentTime.minute,
CurrentTime.second,
RTC_GetCounter()
);
}
void get_timeBCD(sTime * CTime)
{
sTime CurrentTime = TimetoBCD(RTC_GetCounter());
MemCpy(CTime, &CurrentTime, sizeof(sTime));
}
/******************* (C) COPYRIGHT 2013 Robulink Technology Ltd.*****END OF FILE****/