新聞中心

EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > 基于STM32內(nèi)部RTC的時(shí)鐘程序

基于STM32內(nèi)部RTC的時(shí)鐘程序

作者: 時(shí)間:2016-11-29 來源:網(wǎng)絡(luò) 收藏
在網(wǎng)站上找了一些軟件時(shí)鐘程序,在秒時(shí)與日歷轉(zhuǎn)換時(shí),大多是逐年計(jì)算,計(jì)算周期會(huì)隨著年份增加,而增多。于是自己寫了一個(gè)簡(jiǎn)化的秒時(shí)與日歷轉(zhuǎn)換程序,按閏年周期進(jìn)行除法運(yùn)算,計(jì)算周期固定,不隨秒時(shí)與基礎(chǔ)年時(shí)間差增長(zhǎng)而增長(zhǎng),效率明顯提高。

程序帶有閏年計(jì)算與星期計(jì)算,基礎(chǔ)年為2001年1月1日0時(shí)0分0秒,算法可支持到3200年2月28日23時(shí)59分59秒。但由于RTC計(jì)數(shù)器是32位,所以硬件只能支持到2137年2月7日6時(shí)28分15秒,也足夠使用了。

本文引用地址:http://m.butianyuan.cn/article/201611/323216.htm

以下為程序代碼:

/****************************************************************************
* 函數(shù)名: GetRTCWeek
* 功 能: 計(jì)算Week
* 輸 入: 秒時(shí)
* 輸 出: 無.
* 返 回: 星期
*/
//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;
}

/****************************************************************************
* 函數(shù)名: GetSecondFromDateTime
* 功 能: 基于2001/1/1/00:00:00的日期計(jì)算秒時(shí)
* 輸 入: RTC_T 日期時(shí)間結(jié)構(gòu)體
* 輸 出: 無.
* 返 回: 秒時(shí)
*/
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){//百年不潤(rùn)
sec -= y/100;
}
if(y/400){//四百年再潤(rùn)
sec += y/400;
}
y %= 4;
sec += y * DAY_OF_YEAR;
ptr = DayOfCurrentMonthNormal;
if(y == 3 && _tRtc->month > 2 && IsRTCLeapYear(_tRtc->year)){//當(dāng)前年為潤(rùn)年,并且月份已過2月,天數(shù)加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;
}

/****************************************************************************
* 函數(shù)名: GetDateTimeFromSecond
* 功 能: 由秒時(shí)計(jì)算基?001/1/1/00:00:00的日期
* 輸 入: RTC_T 日期時(shí)間結(jié)構(gòu)體
* 輸 出: 無.
* 返 回: 無
*/
void GetDateTimeFromSecond(u32 lSec, RTC_T *_tRtc)
{
uint16_t y,m;
u32 lDay;
const u32 *ptr;

lDay = lSec / SECOND_OF_DAY; /* 轉(zhuǎn)為基于天的時(shí)間 */
_tRtc->year = RTC_BASE_YEAR;//基數(shù)年份
y = lDay / DAY_OF_FOURYEAR;
y *= 4;
_tRtc->year += y;
lDay %= DAY_OF_FOURYEAR;
if(y/100){//百年不潤(rùn)
lDay += y/100;
}
if(y/400){//四百年再潤(rùn)
lDay -= y/400;
}
y = lDay / DAY_OF_YEAR;
_tRtc->year += y; /* 得到年份 */
lDay %= DAY_OF_YEAR;
ptr = DayOfCurrentMonthNormal;
if(y == 3 && IsRTCLeapYear(_tRtc->year)){//當(dāng)前年為潤(rùn)年,并且月份已過2月,天數(shù)加1
ptr = DayOfCurrentMonthLeap;
}
for(m=12;m>1;m--){ /* 查詢?cè)路?*/
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;
}



評(píng)論


技術(shù)專區(qū)

關(guān)閉