您的位置 首页 IC

根据STM32内部RTC的时钟程序

在网站上找了一些软件时钟程序,在秒时与日历转换时,大多是逐年计算,计算周期会随着年份增加,而增多。于是自己写了一个简化的秒时与日历

在网站上找了一些软件时钟程序,在秒时与日历转化时,大多是逐年核算,核算周期会跟着年份添加,而增多。所以自己写了一个简化的秒时与日历转化程序,按闰年周期进行除法运算,核算周期固定,不随秒时与根底年时刻差增加而增加,功率明显提高。

程序带有闰年核算与星期核算,根底年为2001年1月1日0时0分0秒,算法可支撑到3200年2月28日23时59分59秒。但由于RTC计数器是32位,所以硬件只能支撑到2137年2月7日6时28分15秒,也满足使用了。

以下为程序代码:

/****************************************************************************
* 函数名: GetRTCWeek
* 功 能: 核算Week
* 输 入: 秒时
* 输 出: 无.
* 返 回: 星期
*/
//u8 GetRTCWeek(RTC_T *_tRtc)
u8 GetRTCWeek(u32 lDay)
{
//u32 lDay;
//lDay = GetSecondFromDateTime(_tRtc)/SECOND_OF_DAY;
lDay /= SECOND_OF_DAY;
lDay += RTC_BASE_WEEK;
lDay %= 7;
return (u8)lDay;
}

/****************************************************************************
* 函数名: GetSecondFromDateTime
* 功 能: 根据2001/1/1/00:00:00的日期核算秒时
* 输 入: RTC_T 日期时刻结构体
* 输 出: 无.
* 返 回: 秒时
*/
uint32_t GetSecondFromDateTime(RTC_T *_tRtc)
{
u32 y,sec,fy;
const u32 *ptr;
y = (u32)((_tRtc->year – (u16)RTC_BASE_YEAR)&0x0000FFFF);
fy = y / 4;
sec = fy * DAY_OF_FOURYEAR;
if(y/100){//百年不润
sec -= y/100;
}
if(y/400){//四百年再润
sec += y/400;
}
y %= 4;
sec += y * DAY_OF_YEAR;
ptr = DayOfCurrentMonthNormal;
if(y == 3 && _tRtc->month > 2 && IsRTCLeapYear(_tRtc->year)){//当前年为润年,而且月份已过2月,天数加1
ptr = DayOfCurrentMonthLeap;
}
sec += ptr[_tRtc->month];
sec += _tRtc->day – 1;
sec *= 24;
sec += _tRtc->hour;
sec *= 60;
sec += _tRtc->minute;
sec *= 60;
sec += _tRtc->second;
return sec;
}

/****************************************************************************
* 函数名: GetDateTimeFromSecond
* 功 能: 由秒时核算基?001/1/1/00:00:00的日期
* 输 入: RTC_T 日期时刻结构体
* 输 出: 无.
* 返 回: 无
*/
void GetDateTimeFromSecond(u32 lSec, RTC_T *_tRtc)
{
uint16_t y,m;
u32 lDay;
const u32 *ptr;

lDay = lSec / SECOND_OF_DAY; /* 转为根据天的时刻 */
_tRtc->year = RTC_BASE_YEAR;//基数年份
y = lDay / DAY_OF_FOURYEAR;
y *= 4;
_tRtc->year += y;
lDay %= DAY_OF_FOURYEAR;
if(y/100){//百年不润
lDay += y/100;
}
if(y/400){//四百年再润
lDay -= y/400;
}
y = lDay / DAY_OF_YEAR;
_tRtc->year += y; /* 得到年份 */
lDay %= DAY_OF_YEAR;
ptr = DayOfCurrentMonthNormal;
if(y == 3 && IsRTCLeapYear(_tRtc->year)){//当前年为润年,而且月份已过2月,天数加1
ptr = DayOfCurrentMonthLeap;
}
for(m=12;m>1;m–){ /* 查询月份 */
if(lDay >= ptr[m]) {
lDay -= ptr[m];
break;
}
}
_tRtc->month = m;
_tRtc->day = lDay+1;
_tRtc->week = GetRTCWeek(lSec);

lSec = lSec % SECOND_OF_DAY;
_tRtc->hour = lSec / SECOND_OF_HOUR;
lSec %= SECOND_OF_HOUR;
_tRtc->minute = lSec / SECOND_OF_MINUTE;
_tRtc->second = lSec % SECOND_OF_MINUTE;
}

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/bandaoti/319316.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部