⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rtc.c

📁 FE42X单相防窃电电表DEMO(编译器 AQ430 AQ430 V2.0.6.5)
💻 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 + -