新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > 基于STM32內部RTC的時鐘程序

        基于STM32內部RTC的時鐘程序

        作者: 時間:2016-11-29 來源:網絡 收藏
        在網站上找了一些軟件時鐘程序,在秒時與日歷轉換時,大多是逐年計算,計算周期會隨著年份增加,而增多。于是自己寫了一個簡化的秒時與日歷轉換程序,按閏年周期進行除法運算,計算周期固定,不隨秒時與基礎年時間差增長而增長,效率明顯提高。

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

        本文引用地址:http://www.104case.com/article/201611/323216.htm

        以下為程序代碼:

        /****************************************************************************
        * 函數名: 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;
        }



        評論


        技術專區

        關閉
        主站蜘蛛池模板: 兰西县| 象州县| 东明县| 永昌县| 东至县| 晴隆县| 淮阳县| 丹凤县| 巴彦淖尔市| 固阳县| 岫岩| 沙湾县| 澳门| 新沂市| 高台县| 鄂伦春自治旗| 大理市| 循化| 和林格尔县| 潜江市| 临颍县| 清水河县| 中超| 邵东县| 麦盖提县| 什邡市| 长宁区| 鄂温| 饶平县| 西青区| 东莞市| 青河县| 蒙城县| 蓝山县| 和政县| 陈巴尔虎旗| 沾益县| 南木林县| 凉城县| 山阴县| 兴和县|