微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > ARM技术讨论 > 求助啊 STM32RTC学习中一些问题:数据处理上的一些小问题。

求助啊 STM32RTC学习中一些问题:数据处理上的一些小问题。

时间:10-02 整理:3721RD 点击:
最近在论坛逛了下,没接触过STM的RTC,想来学习下,然后移植了yunqian09 的《STM32 rtc 显示年月日 时分秒星期》的帖子。
移植完毕之后发现一些小问题。
现在最让我头疼的是,每当月份跳转的时候出现天数加1月份不跳的情况,
例如:
Date: 2013年05月31日 Time: 23:59:58  week:5
Date: 2013年05月31日 Time: 23:59:59  week:5
Date: 2013年05月32日 Time: 00:00:00  week:6  (!就是这样)
Date: 2013年06月01日 Time: 00:00:01  week:6
每个月份,年份跳转时候都会出现。闰年29号走完,会出现个30号。
我是用串口进行显示,RTC秒中断时用回调函数通知“观察者”。
调了一整天,郁闷死了。
贴出计算源码。 希望大神指教
#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)                //每天秒数
static UINT32 Month_Days_Accu_C[] = {31,59,90,120,151,181,212,243,273,304,334,365,0};  //平年月累加列表
static UINT32 Month_Days_Accu_L[] = {0,31,60,91,121,152,182,213,244,274,305,335,366};  //闰年月累加列表
static UINT32 Year_Secs_Accu[]    = {0,31622400, 63158400, 94694400, 126230400};           //1闰3平年总秒数累加列表
static UINT32 Month_Secs_Accu_C[] = {0,2678400, 5097600,  7776000,  10368000,                   //平年每月总秒数累加
                                     13046400,  15638400, 18316800, 20995200,
                                                        23587200,  26265600, 28857600, 31536000};
static UINT32 Month_Secs_Accu_L[] = {0,2678400, 5184000,  7862400,  10454400,                   //闰年每月总秒数累加列表
                                     13132800,  15724800, 18403200, 21081600,
                                                     23673600,  26352000, 28944000, 31622400};
//计算设置时间的总秒数
static UINT32 Time_Regulate(RTC_TIME *pTime)
{
        UINT32 LeapYear, ComYear, TotSeconds, TotDays;
/*        DBG(TRACE("Input Information: \r\n"));
        DBG(TRACE("Year: %d\r\n",     pTime->Year));
        DBG(TRACE("Month: %d\r\n",   pTime->Month));
        DBG(TRACE("Day: %d\r\n",       pTime->Day));
        DBG(TRACE("Hour: %d\r\n",     pTime->Hour));
        DBG(TRACE("Minute: %d\r\n",  pTime->Minute));
        DBG(TRACE("Second: %d\r\n", pTime->Second));         */
        if(2000==pTime->Year)                         //平润年计算  从2000年起,可计算后130年左右 不支持2000年以前的时间输入
        {
                LeapYear = 0;
        }        
        else
        {
                LeapYear = (pTime->Year - 2000 - 1)/4 + 1;
        }
        ComYear = (pTime->Year - 2000) - LeapYear;
        if(pTime->Year%4 != 0)                                                                                                                           
        {        //平年
                TotDays = LeapYear*366 + ComYear*365 + Month_Days_Accu_C[pTime->Month - 1] + (pTime->Day -1);
        }
        else
        {        //润年
                TotDays = LeapYear*366 + ComYear*365 + Month_Days_Accu_L[pTime->Month - 1] + (pTime->Day -1);
        }
        TotSeconds = TotDays*SecsPerDay + pTime->Hour*3600 + pTime->Minute*60 + pTime->Second;
        return TotSeconds;                //返回总秒数用于计算
}

//年月日计算星期几        输入值 年、月、日
static UCHAR YearMonthDayToWeek(INT16 Year, UCHAR Month, UINT16 Day)
{
        static INT m_Days[] = {0,31,28,31,30,31,30,31,31,30,31,30 };   //平年每月天数表
        INT i, y;         
        UCHAR Week;         
        y = Year - 1;
        for(i = 0; i<Month; ++i)
        {
                Day += m_Days[i];
        }
        if(Month > 2)
        {
                if(((0 == Year%400)) || (0 == (Year&3) &&(Year%100)))
                {
                        ++Day;
                }
        }
        Week = (y + y/4 - y/100 + y/400 + Day)%7;
        if(NULL==Week)                                                                     //修复设定初值时,刚好为星期天,显示为0的问题
        {
                Week = 7;
        }
        return Week;
}
//计算 年、月、日、时、分、秒
static void ComputeTime(UINT32 TimeVar,RTC_TIME *pTime)
{
        INT32 FourYearNum, YearNum, OffSec,
                  NumDay, FourYearOff = 0;
        UINT32 i;
        UINT32 TY   = 0,  TM   = 1,  TD  = 0;
        UINT32 THH = 0,  TMM = 0, TSS = 0;
        
        FourYearNum = TimeVar/SecsPerFourYear;
        OffSec          = TimeVar%SecsPerFourYear;
        i = 1;        
        while(OffSec >Year_Secs_Accu[i++])
        {
                FourYearOff++;
        }
        YearNum = FourYearNum*4 + FourYearOff;
        TY = 2000 + YearNum;
        OffSec = OffSec - Year_Secs_Accu[i-2];
        i = 0;
        if(TY%4)
        {
                while(OffSec >Month_Secs_Accu_C[i++]);
                TM = i - 1;
                OffSec = OffSec - Month_Secs_Accu_C[i-2];
        }
        else
        {
                while(OffSec >Month_Secs_Accu_L[i++]);
                TM = i - 1;
                OffSec = OffSec - Month_Secs_Accu_L[i-2];
        }
        NumDay = OffSec/SecsPerDay;
        OffSec   = OffSec%SecsPerDay;
        TD        = NumDay + 1;
        THH      =  OffSec/3600;
        TMM     = (OffSec%3600)/60;
        TSS      = (OffSec%3600)%60;
               
        pTime->Year      = TY;                                                          //将算出数据存入结构体                                                  
        pTime->Month   = TM;
        pTime->Day       = TD;
        pTime->Hour     = THH;
        pTime->Minute  = TMM;
        pTime->Second = TSS;
        pTime->Week   = YearMonthDayToWeek(TY,TM,TD);             //计算星期几
}

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top