求助啊 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); //计算星期几
}
移植完毕之后发现一些小问题。
现在最让我头疼的是,每当月份跳转的时候出现天数加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); //计算星期几
}
