新聞中心

        EEPW首頁 > 嵌入式系統(tǒng) > 設計應用 > STM32 萬年歷 顯示年月日 時分秒 星期

        STM32 萬年歷 顯示年月日 時分秒 星期

        作者: 時間:2016-11-13 來源:網絡 收藏
        基于STM32處理器 的RTC只是個能靠電池維持運行的32位定時器! 并不像實時時鐘芯片,讀出來就是年月日時分秒。

        此程序 第一次運行時候 從超級終端 輸入時間
        關鍵代碼

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

        /*******************************************************************************
        * Function Name : Time_Regulate
        * Description : Returns the time entered by user, using Hyperterminal.
        * Input : None
        * Output : None
        * Return : Current time RTC counter value
        *******************************************************************************/
        //u32 Month_Days[13] = {0,31,28,31,30, 31, 30, 31, 31, 30, 31, 30, 31};

        u32 Month_Days_Accu_C[13] = {0,31,59,90,120,151,181,212,243,273,304,334,365};
        u32 Month_Days_Accu_L[13] = {0,31,60,91,121,152,182,213,244,274,305,335,366};
        #define SecsPerDay (3600*24)

        u32 Time_Regulate(void)
        {
        #if 1
        u32 Tmp_Year=0xFFFF, Tmp_Month=0xFF, Tmp_Date=0xFF;
        u32 LeapY, ComY, TotSeconds, TotDays;
        #endif
        u32 Tmp_HH = 0xFF, Tmp_MM = 0xFF, Tmp_SS = 0xFF;

        printf("rn==============Time Settings=====================================");

        #if 1
        printf("rn Please Set Year");
        while(Tmp_Year == 0xFFFF)
        {
        /*32-bit counter at Second Unit--> 4*1024*1024(s) --> 49710(day) --> 136(year)*/
        Tmp_Year = USART_Scanf(2136);
        }
        //Tmp_Year=2010;
        printf(": %d", Tmp_Year);

        printf("rn Please Set Month");
        while(Tmp_Month == 0xFF)
        {
        Tmp_Month = USART_Scanf(12);
        }
        printf(": %d", Tmp_Month);

        printf("rn Please Set Date");
        while(Tmp_Date == 0xFF)
        {
        Tmp_Date = USART_Scanf(31);
        }
        printf(": %d", Tmp_Date);
        #endif

        printf("rn Please Set Hours");
        while(Tmp_HH == 0xFF)
        {
        Tmp_HH = USART_Scanf(23);
        }
        printf(": %d", Tmp_HH);

        printf("rn Please Set Minutes");
        while(Tmp_MM == 0xFF)
        {
        Tmp_MM = USART_Scanf(59);
        }
        printf(": %d", Tmp_MM);;

        printf("rn Please Set Seconds");
        while(Tmp_SS == 0xFF)
        {
        Tmp_SS = USART_Scanf(59);
        }
        printf(": %d", Tmp_SS);

        #if 1
        {
        /* change Year-Month-Data-Hour-Minute-Seconds into X(Second) to set RTC->CNTR */
        if(Tmp_Year==2000)
        LeapY = 0;
        else
        LeapY = (Tmp_Year - 2000 -1)/4 +1;

        ComY = (Tmp_Year - 2000)-(LeapY);

        if (Tmp_Year%4)
        //common year
        TotDays = LeapY*366 + ComY*365 + Month_Days_Accu_C[Tmp_Month-1] + (Tmp_Date-1);
        else
        //leap year
        TotDays = LeapY*366 + ComY*365 + Month_Days_Accu_L[Tmp_Month-1] + (Tmp_Date-1);

        TotSeconds = TotDays*SecsPerDay + (Tmp_HH*3600 + Tmp_MM*60 + Tmp_SS);
        }
        #endif

        /* Return the value to store in RTC counter register */
        //return((Tmp_HH*3600 + Tmp_MM*60 + Tmp_SS));
        return TotSeconds;
        }

        ===============================================

        /**
        * @brief Displays the current time.
        * @param TimeVar: RTC counter value.
        * @retval None
        */

        #define SecsPerComYear 3153600//(365*3600*24)
        #define SecsPerLeapYear 31622400//(366*3600*24)
        #define SecsPerFourYear 126230400//((365*3600*24)*3+(366*3600*24))
        #define SecsPerDay (3600*24)

        s32 Year_Secs_Accu[5]={0,
        31622400,
        63158400,
        94694400,
        126230400};

        s32 Month_Secs_Accu_C[13] = { 0,
        2678400,
        5097600,
        7776000,
        10368000,
        13046400,
        15638400,
        18316800,
        20995200,
        23587200,
        26265600,
        28857600,
        31536000};
        s32 Month_Secs_Accu_L[13] = {0,
        2678400,
        5184000,
        7862400,
        10454400,
        13132800,
        15724800,
        18403200,
        21081600,
        23673600,
        26352000,
        28944000,
        31622400};
        void Time_Display(uint32_t TimeVar)
        {
        #if 0
        uint32_t THH = 0, TMM = 0, TSS = 0;

        /* Compute hours */
        THH = TimeVar / 3600;
        /* Compute minutes */
        TMM = (TimeVar % 3600) / 60;
        /* Compute seconds */
        TSS = (TimeVar % 3600) % 60;

        printf("Time: %0.2d:%0.2d:%0.2dr", THH, TMM, TSS);
        #endif
        //----------------------------------------------
        #if 1
        u32 TY = 0, TM = 1, TD = 0;
        s32 Num4Y,NumY, OffSec, Off4Y = 0;
        u32 i;
        //s32 NumDay, OffDay;
        s32 NumDay;
        #endif
        u32 THH = 0, TMM = 0, TSS = 0;
        #if 0
        /* Compute hours */
        THH = TimeVar/3600;
        /* Compute minutes */
        TMM = (TimeVar % 3600)/60;
        /* Compute seconds */
        TSS = (TimeVar % 3600)% 60;
        #endif
        #if 1
        {
        Num4Y = TimeVar/SecsPerFourYear;
        OffSec = TimeVar%SecsPerFourYear;

        i=1;
        while(OffSec > Year_Secs_Accu[i++])
        Off4Y++;

        /* Numer of Complete Year */
        NumY = Num4Y*4 + Off4Y;
        /* 2000,2001,...~2000+NumY-1 complete year before, so this year is 2000+NumY*/
        TY = 2000+NumY;

        OffSec = OffSec - Year_Secs_Accu[i-2];

        /* Month (TBD with OffSec)*/
        i=0;
        if(TY%4)
        {// common year
        while(OffSec > Month_Secs_Accu_C[i++]);
        TM = i-1;
        OffSec = OffSec - Month_Secs_Accu_C[i-2];
        }
        else
        {// leap year
        while(OffSec > Month_Secs_Accu_L[i++]);
        TM = i-1;
        OffSec = OffSec - Month_Secs_Accu_L[i-2];
        }

        /* Date (TBD with OffSec) */
        NumDay = OffSec/SecsPerDay;
        OffSec = OffSec%SecsPerDay;
        TD = NumDay+1;

        /* Compute hours */
        THH = OffSec/3600;
        /* Compute minutes */
        TMM = (OffSec % 3600)/60;
        /* Compute seconds */
        TSS = (OffSec % 3600)% 60;
        }
        #endif

        printf("Date: %0.4d-%0.2d-%0.2d Time: %0.2d:%0.2d:%0.2dr",TY, TM, TD,THH, TMM, TSS);
        //----------------------------------------------------
        }

        ===========================================

        /**
        * @brief Gets numeric values from the hyperterminal.
        * @param None
        * @retval None
        */

        //注意返回值一定不能是 uint8_t
        uint32_t USART_Scanf(uint32_t value)
        {
        u32 index = 0;
        u32 tmp[4] = {0, 0};
        u32 Num;

        if (value==2136)
        Num = 4;
        else
        Num = 2;

        while(index < Num)
        {
        /* Loop until RXNE = 1 */
        while(USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET)
        {
        }
        tmp[index++] = (USART_ReceiveData(USART1));
        if((tmp[index - 1] < 0x30) || (tmp[index - 1] > 0x39))
        {
        printf("nrPlease enter valid number between 0 and 9");
        index--;
        }
        }
        /* Calculate the Corresponding value */
        if (value!=2136)
        index = ((tmp[0] - 0x30) * 10) + (tmp[1] - 0x30);
        else
        index = ((tmp[0] - 0x30) * 1000) + ((tmp[1] - 0x30) * 100) + ((tmp[2] - 0x30) * 10) + (tmp[3] - 0x30);
        /* Checks */
        if(index > value)
        {
        printf("nrPlease enter valid number between 0 and %d", value);
        return 0xFF;
        }
        return index;
        }

        =============

        程序下載地址

        顯示年月日 時分秒的程序(注意是板凳的回復)
        轉自Tony嵌入式論壇,地址:http://www.cevx.com/bbs/thread-26329-1-1.html

        ===================

        附:年月日轉化為星期的函數

        int Ymd2Wday(int year, int month, int days) //年月日 to 星期 ******* 已驗證******
        {
        static int mdays[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30 };
        int i, y = year - 1;
        for (i=0; iif (month>2) { // Increment date if this is a leap year after February
        if (((year%400)==0) || ((year&3)==0 && (year%100))) ++days;
        }
        return (y+y/4-y/100+y/400+days)%7;
        }

        //由年月日計算星期
        //判斷是否是閏年,閏年2月是29天 公式:366%7=2;如真是是要計算萬年用if(((y%4==0)&&(y%100!=0))||(y%400==0))) 這里為了減少編譯代碼長度
        unsigned char getweek(unsigned char year,unsigned char month,unsigned char day)
        {
        unsigned char week,tp;
        tp=0;week=5; //初始化2000-01-01星期六
        while(tp!=year){ //處理年(2000開始)
        week++; //是上一年的星期的下一天 公式:365%7=1
        if(tp%4==0)week++; //判斷是否是閏年,閏年2月是29天 公式:366%7=2
        tp++; //下一年的1月1日
        }
        tp=1;
        while(tp!=month){ //處理月(1月開始)
        switch(tp){
        case 1:case 3:case 5:case 7:case 8:case 10:case 12: week=week+3;break; //大月天數31%7
        case 2: if(year%4==0)week++;break; //閏月天數,閏年2月是29天 公式:366%7=2 29%7
        case 4:case 6:case 9:case 11: week=week+2;break; //小月天數30%7
        }
        tp++; //處理月
        }
        week=week+day; //處理日(從1日開始)
        week=week%7;
        if(week==0) week=7;
        return week; //返回星期
        }

        -------------------------------------------

        我也貢獻一個

        unsigned char week(void)
        {
        int Y;
        unsigned char A;
        Y=2000+t.n;
        /*下面的四條語句用來計算輸入日期的星期數,是程序的核心部分,缺一不可 */
        A = Y>0?(5+(Y+1)+(Y-1)/4-(Y-1)/100+(Y-1)/400)%7:(5+Y+Y/4-Y/100+Y/400)%7;
        A = t.y>2?(A+2*(t.y+1)+3*(t.y+1)/5)%7:(A+2*(t.y+2)+3*(t.y+2)/5)%7;
        if (((Y%4 == 0 && Y%100 != 0) || (Y%100==0 &&Y%400 == 0)) && t.y>2) {A =(A+1)%7;}
        A=(A+t.r)%7;
        if (A==0) A=8;/*星期日顯示 8*/
        return A;
        }

        當前的
        t.n 年
        t.y 月
        t.r 日



        關鍵詞: STM32萬年

        評論


        技術專區(qū)

        關閉
        主站蜘蛛池模板: 西青区| 象山县| 双桥区| 梁河县| 曲麻莱县| 修文县| 静宁县| 寻乌县| 博罗县| 彰化县| 鹿泉市| 高邮市| 凤阳县| 钦州市| 安远县| 桃江县| 白城市| 清徐县| 秦安县| 申扎县| 全椒县| 天镇县| 田阳县| 福鼎市| 曲阳县| 花莲市| 安徽省| 新河县| 深圳市| 新绛县| 广东省| 潼关县| 健康| 兴仁县| 安溪县| 射洪县| 清徐县| 安国市| 涿州市| 通榆县| 青州市|