📄 rtc.c
字号:
/********************************************************************************
* 杭州利尔达 *
* MSP430FE42X单相防窃电多功能电表平台 *
* ----- ESP SD16实现 *
* *
* *
* 说明:本软件为杭州利尔达单相防窃电多功能电表DEMO软件 *
* *
*********************************************************************************/
#include "msp430xe42x.h"
#include "emeter_cfg.h"
#include "globe.h"
#define RTC_INCONSISTENT 0
#define RTC_CHANGED_SECOND 1
#define RTC_CHANGED_MINUTE 2
#define RTC_CHANGED_HOUR 3
#define RTC_CHANGED_DAY 4
#define RTC_CHANGED_MONTH 5
#define RTC_CHANGED_YEAR 6
// 实时时钟偏差值 PPM*1000
static int32 rtc_correction;
const int8 month_lengths[13] =
{
00,
31, 28, 31,
30, 31, 30,
31, 31, 30,
31, 30, 31
};
void set_rtc_sumcheck(void)
{
rtc.sumcheck = ~(rtc.second + rtc.minute + rtc.hour + rtc.day + rtc.month + rtc.year);
}
/* This can be used to check the integrity of the RTC after a reset */
int check_rtc_sumcheck(void)
{
return rtc.sumcheck == ((~(rtc.second + rtc.minute + rtc.hour + rtc.day + rtc.month + rtc.year)) & 0xFF);
}
/* Bump the RTC by a second, and return an indication of the most significant
element of the date to have changed. Maintain a sumcheck byte to help check
for corrupted RTC settings after a reset. */
int bump_rtc(void)
{
/* First check the consistency of the current rtc setting. If it is inconsistent,
(i.e. has a bad sumcheck) do not bump it. */
if (!check_rtc_sumcheck())
return RTC_INCONSISTENT;
if (++rtc.second < 60)
{
set_rtc_sumcheck();
return RTC_CHANGED_SECOND;
}
rtc.second = 0;
if (++rtc.minute < 60)
{
set_rtc_sumcheck();
return RTC_CHANGED_MINUTE;
}
rtc.minute = 0;
if (++rtc.hour < 24)
{
set_rtc_sumcheck();
return RTC_CHANGED_HOUR;
}
rtc.hour = 0;
if ((rtc.month == 2 && (rtc.year & 3) == 0 && rtc.day < 29)
||
rtc.day < month_lengths[rtc.month])
{
++rtc.day;
set_rtc_sumcheck();
return RTC_CHANGED_DAY;
}
rtc.day = 1;
if (++rtc.month <= 12)
{
set_rtc_sumcheck();
return RTC_CHANGED_MONTH;
}
rtc.month = 1;
++rtc.year;
set_rtc_sumcheck();
return RTC_CHANGED_YEAR;
}
/* Return the current day of the week, based on the RTC. */
int weekday(void)
{
int i;
int days;
/* This works for years 2000-2099 */
/* Result is 0=Sunday, 1=Monday, etc. */
/* Allow for the day of the month */
days = rtc.day + 6;
/* Allow for the months to date this year... */
for (i = 1; i < rtc.month; i++)
days += month_lengths[i];
/* ...with a little offset if we are early in a leap year */
if ((rtc.year & 0x03) == 0 && rtc.month <= 2)
days--;
/* Allow for the years... */
days += rtc.year;
/* ...and a little extra for the leap years */
days += (rtc.year >> 2);
days %= 7;
return days;
}
void rtc_bumper(void)
{
int i;
i = bump_rtc();
/* And now, a series of optional routines to get actions to take
place at various intervals. Remember, we are in an interrupt
routine. Do not do anything very complex here. If a complex action
is needed set a flag in a simple routine and do the main work in
the non-interrupt code's main loop. */
#if BATTERY_MONITOR_SUPPORT
if (i >= RTC_CHANGED_MINUTE)
test_battery();
#endif
#if PER_SECOND_ACTIVITY_SUPPORT
if (i >= RTC_CHANGED_SECOND)
per_second_activity();
#endif
#if PER_MINUTE_ACTIVITY_SUPPORT
if (i >= RTC_CHANGED_MINUTE)
per_minute_activity();
#endif
#if PER_HOUR_ACTIVITY_SUPPORT
if (i >= RTC_CHANGED_HOUR)
per_hour_activity();
#endif
#if PER_DAY_ACTIVITY_SUPPORT
if (i >= RTC_CHANGED_DAY)
per_day_activity();
#endif
#if PER_MONTH_ACTIVITY_SUPPORT
if (i >= RTC_CHANGED_MONTH)
per_month_activity();
#endif
#if PER_YEAR_ACTIVITY_SUPPORT
if (i >= RTC_CHANGED_YEAR)
per_year_activity();
#endif
}
void correct_rtc(void)
{
int32 temp =0;
temp = emeter.i_temperature - emeter.ul_TempSampleOffset;
temp = ((((float)temp)/32768.0) * 640.0 - 343.349)/1.257 + 0.5 ; // 加0.5,四舍五入
emeter.i_last_temperature = (int16)temp; // 此时已经是一个摄氏温度值, 用于LCD显示
temp -= 25;
temp = temp*temp*35*CORRECT_TIME;
temp = -temp;
/* 晶体的基本偏差,也就是在常温时25摄氏度时,晶体偏差 */
/* 为了方便处理,在程序中,我们对偏差,包括温度引起的和基本偏差,都放大1000倍 */
temp += CRYSTAL_BASE_CORRECTION;
if (rtc_correction >= 0)
{
rtc_correction += temp;
if (rtc_correction >= 1000000000)
{
rtc_correction -= 1000000000;
/* 累计偏差已达到1秒,我们需要跳过一秒 */
emeter.ui_meter_status |= SKIP_A_SECOND;
}
}
else
{
rtc_correction += temp;
if (rtc_correction <= -1000000000)
{
rtc_correction += 1000000000;
/* 累计偏差已达到1秒,我们需要额外增加一秒 */
rtc_bumper();
}
}
}
/* 定义非初始化全局变量 */
#pragma +norom1
struct rtc_s rtc;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -