UTC:世界标准时间,用来在全球范围内同步时间的方法,通过非常精准的原子钟维护,为抵消地球自转变慢参数的影响,需要不规则的加入闰秒,所以会出现闰年来弥补人为规定的纪年与地球公转产生的差异。
UNIX时间:用来记录时间的流逝,定义为从UTC时间1970年1月1日0时0分0秒开始流逝的秒数,无论身处何地,时间都一样,UNIX系统中计算机内部的时间都是使用这种时间,但是为方便观察,需要转换为年-月-日-时-分-秒的格式。
该代码用于STM32开发板,初始化RTC时钟后,通过UART串口设置并显示时间,此代码仅为部分代码。
#define year_days(a) (((a%100!=0)&&(a%4==0))||(a%400==0))
#define days_in_year(i) (year_days(i) ? 366 : 365) //判断i年是否为闰年
unsigned long days_in_month[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
//一年中各月份天数
struct date_time
{
unsigned long year;
unsigned long month;
unsigned long day;
unsigned long hour;
unsigned long min;
unsigned long sec;
}; //时间结构体
void Time_Display(u32 ticks) //显示时间函数,ticks表示当前时间秒数
{
struct date_time now; //当前时间
unsigned long days; //天数
unsigned long hms; //时分秒
int i;
days = ticks / 86400; //当前时间秒数对应的天数
hms = ticks % 86400; //当前时间秒数对应的不足一天的秒数
now.hour = hms / 3600; //转换所得小时
now.min = (hms % 3600) / 60; //转换所得分钟
now.sec = (hms % 3600) % 60; //转换所得秒
for(i = 1970; days > days_in_year(i); i++) //当天数大于这一年的天数时,年份加1
days -= days_in_year(i);
now.year = i; //转换所得年份
if(year_days(i)) //判断当前年份是否为闰年,得到二月份天数
days_in_month[2] = 29;
else
days_in_month[2] = 28;
for(i = 1; days > days_in_month[i]; i++) //当天数大于这一个月的天数时,月份加1
days -= days_in_month[i];
now.month = i; //转换所得月份
now.day = days + 1; //转换所得日,因没有0日,所以加1
printf("%ld-%ld-%ld %ld:%ld:%ld\n", now.year, now.month, now.day, now.hour, now.min, now.sec);
}
void Set_RTC_Time() //通过UART串口直接设置时间,输入格式为年月日时分秒
{
struct date_time time; //日期结构体
unsigned long days = 0; //天数初始化0
unsigned long ticks; //秒数
int i;
printf("please input the time of now:\n");
scanf("%ld%ld%ld%ld%ld%ld", &time.year,&time.month,&time.day,&time.hour,&time.min,&time.sec);
for(i = 1970; i < time.year; i++) //当年份小于设置年份时,递增
days += days_in_year(i); //天数增加该年天数
if(year_days(i)) //判断当前年份是否为闰年,得到二月份天数
days_in_month[2] = 29;
else
days_in_month[2] = 28;
for(i = 1; i < time.month; i++) //当月份小于设置月份时,递增
days += days_in_month[i]; //天数增加该月天数
days += time.day - 1; //天数增加设置日,且要比设置日少1天
ticks = days * 86400 + time.hour * 3600 + time.min * 60+ time.sec;
//计算设置日期相对于标准日期的秒数
RTC_SetCounter(ticks); //设置RTC寄存器秒数
}
int main(void)
{
unsigned int n;
int i, j;
SysTick_Configure();
Uart1_Configuration();
RTC_Configuration();
RTC_NVIC_Config();
Buzzer_Configuration();
//外设初始化
while(1)
{
Time_Display(RTC_GetCounter());
Delay_us(1000000); //显示所设置时间,间隔一秒
}
}