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

📄 rtc.c

📁 本源码是CORTEX-M3之流明LM3SXXX系列上的RTC程序,此处理器系列不带年月日寄存器,只提供秒寄存器,带有部分算法...
💻 C
字号:
/**********************************************************************************************************************  
文件名:   UARTAPE.c
作者: Viboy    版本: V1.0       日期:2008-08-01
联系方式: QQ:64933886 WEBSITE: www.cortexmcu.com
函数列表说明:
    1. RTC_Init  ---> RTC模块初始化
    2. RTC_Read  ---> RTC读,返回年,月,日,星期,时,分,秒
    3. RTC_Write ---> RTC写,设置当前年,月,日,时,分,秒
    
历史:
      <作者>      <日期>     <版本>   <说明>
      Viboy     2008-08-01    V1.0     初版
***********************************************************************************************************************/
#include <stdio.h>
#include <string.h>
#include <LM3Sxxxx.H>
#include "RTC.h"
#include "config.h"

#define RTC_INFOR_OK	0
#define FORMAT_ERR		1

typedef struct
{
	int month;
	int	total;
}DAY_TOTAL;

const DAY_TOTAL  DayToatlBefor[12] = 
{
	{1,31}, {2,59},
	{3,90},	{4,120},
	{5,151},{6,181},
	{7,212},{8,243},
	{9,273},{10,304},
	{11,334},{12,365}
};

const DAY_TOTAL  Day[12] = 
{
	{1,31},	{2,28},
	{3,31},	{4,30},
	{5,31},	{6,30},
	{7,31},	{8,31},
	{9,30},	{10,31},
	{11,30},{12,31}
};
/*********************************************************************************************************
函数名称: leap_year
功能描述: 闰年判断
输 入:   year		待判断的年份
输  出:   1    闰年
          0    平年
*********************************************************************************************************/
static INT8U leap_year(INT16U nYear)
{
  if(nYear % 4 != 0) return 0;
  if(nYear % 100 != 0) return 1;
  return (INT8U)(nYear % 400 == 0);
}
/*********************************************************************************************************************
函数名称: WeekDayNum	         
功能描述: Determines the week number, the day number and the week day number
输 入  : nyear,nmonth,nday	
输 出  : weekday  	 	                 
*********************************************************************************************************************/
static INT8U WeekDayNum(INT32U nyear, INT8U nmonth, INT8U nday)
{
	INT32U weeknum = 0, weekday = 0, daycount = 0;
	INT32U a = 0, b = 0, c = 0, s = 0, e = 0, f = 0, g = 0, d = 0;
	INT32S n = 0;

	if(nmonth < 3)
	{
		a = nyear - 1;
	}
	else
	{
		a = nyear;
	}
  
	b = (a/4) - (a/100) + (a/400);
	c = ((a - 1)/4) - ((a - 1)/100) + ((a - 1)/400);
	s = b - c;

	if(nmonth < 3)
	{
		e = 0;
		f =  nday - 1 + 31 * (nmonth - 1);
	}
	else
	{
		e = s + 1;
		f = nday + (153*(nmonth - 3) + 2)/5 + 58 + s; 
	}
	
	g = (a + b) % 7;
	d = (f + g - e) % 7;
	n = f + 3 - d;
	
	if (n < 0)
	{
		weeknum = 53 - ((g - s)/5);
	}
	else if (n > (364 + s))
	{
		weeknum = 1;
	}
	else
	{
		weeknum = (n/7) + 1;
	}
	weekday  = d;
	daycount = f + 1;
	
	weeknum  = weeknum;    /* 一年中的第几个星期在此没有用上,防止编译警告 */
	daycount = daycount;   /* 同上 */

	return (INT8U)weekday;
}
/*********************************************************************************************************************
函数名称: Date_Update	         
功能描述: Updates date when time is 23:59:59
输 入  : date_s
输 出  : None  	 	                 
*********************************************************************************************************************/
static void Date_Update(RTC_INFOR* date_s)
{
  if(date_s->month == 1 || date_s->month == 3 || date_s->month == 5 || date_s->month == 7 ||
     date_s->month == 8 || date_s->month == 10 || date_s->month == 12)
  {
    if(date_s->day < 31)
    {
      date_s->day++;
    }
    /* Date structure member: date_s.day = 31 */
    else
    {
      if(date_s->month != 12)
      {
        date_s->month++;
        date_s->day = 1;
      }
      /* Date structure member: date_s.day = 31 & date_s.month =12 */
      else
      {
        date_s->month = 1;
        date_s->day = 1;
        date_s->year++;
      }
    }
  }
  else if(date_s->month == 4 || date_s->month == 6 || date_s->month == 9 ||
          date_s->month == 11)
  {
    if(date_s->day < 30)
    {
      date_s->day++;
    }
    /* Date structure member: date_s.day = 30 */
    else
    {
      date_s->month++;
      date_s->day = 1;
    }
  }
  else if(date_s->month == 2)
  {
    if(date_s->day < 28)
    {
      date_s->day++;
    }
    else if(date_s->day == 28)
    {
      /* Leap year */
      if(leap_year(date_s->year))
      {
        date_s->day++;
      }
      else
      {
        date_s->month++;
        date_s->day = 1;
      }
    }
    else if(date_s->day == 29)
    {
      date_s->month++;
      date_s->day = 1;
    }
  }
}
/*********************************************************************************************************************
函数名称: Time_Update	         
功能描述: Updates time when time is 59:59
输 入  : date_s
输 出  : None  	 	                 
*********************************************************************************************************************/
static void Time_Update(RTC_INFOR* date_s)
{
	if(date_s->minute < 59)
	{
	  date_s->minute++;
	}
	else
	{
	  date_s->hour++;
	  date_s->minute = 0;
	}
}
/*********************************************************************************************************************
函数名称: time_acount_gap	         
功能描述: 将年,月,日,时,分,秒转换成RTC的计数值	
输 入: atime ---> 时间结构
        err   ---> 返回状态码
输 出: 计数值             
*********************************************************************************************************************/
static INT32U time_acount_gap(RTC_INFOR atime, INT8S* err)
{
	const INT8U month_days[] = {31,28,31,30,31,30,31,31,30,31,30,31};	
	INT8U year;	
	INT32U second   = 0;
	INT32U sec_temp= 0;
	INT32U DayTotal= 0;
	INT32U TotalDay = 0;
	INT32U i;
	
	*err = FORMAT_ERR;	
	
	/* 2008 ~ 2099 */
	if(atime.year < 2008 || atime.year > 2099 || atime.month < 1 || atime.month > 12)
	{
		return 0;
	}

	if(atime.day < 1 || atime.day > month_days[atime.month - 1])
	{
		return 0;
	}

	if(atime.month == 2)
	{
		if(atime.year % 4 != 0)
		{
			if(atime.day == 29)return 0;
		}
	}
	if(atime.hour > 23 || atime.minute > 59 || atime.second > 59)
	{
		return 0;
	}
	*err = RTC_INFOR_OK;	
	
	year  = atime.year - 2008;
	if (atime.month == 1) 
	{
		DayTotal = atime.day - 1;
	}
	else 
	{
		DayTotal = DayToatlBefor[atime.month-2].total + atime.day - 1;
	}

	if (atime.month>2)	
	{
		if(leap_year(atime.year))
		{
			DayTotal = DayTotal + 1;
		}	
	}

	for (i=0;i<year;i++)
	{
		TotalDay = TotalDay + leap_year(2008+i);	
	}
	
	TotalDay = TotalDay + year * 365 + DayTotal;	
	sec_temp = atime.hour * 3600 + atime.minute * 60 + atime.second;		
	second = TotalDay * 86400 + sec_temp;
	
	return second;
}
/*********************************************************************************************************************
函数名称: acount_time_gap	         
功能描述: 读取当前年,月,日,时,分,秒	
输 入: atime  ---> 接收缓冲
        acount ---> RTC计数值  		
输 出: 无  	 	                 
*********************************************************************************************************************/
static void acount_time_gap(RTC_INFOR* atime, INT32U acount)
{
	INT32U sum_seconds = acount;
	INT32U i;
	RTC_INFOR init_rtc;
	
	/* 基准时间为: 2008-01-01 00:00:00 */
	init_rtc.year   = 2008;
	init_rtc.month  = 1;
	init_rtc.day    = 1;
	init_rtc.hour   = 0;
	init_rtc.minute = 0;
	init_rtc.second = 0;
	
	if( sum_seconds / 86400 != 0 )
	{
		for( i=0; i< (sum_seconds / 86400); i++ )
		{
			Date_Update(&init_rtc);
		}
	}	
	sum_seconds = sum_seconds % 86400;
	
	if( sum_seconds / 60 != 0 )
	{
		for( i=0; i< (sum_seconds / 60); i++)
		{
			Time_Update(&init_rtc);
		}
	}
	init_rtc.second = (INT8U)(sum_seconds % 60);

	atime->year   = init_rtc.year;
	atime->month  = init_rtc.month;
	atime->day    = init_rtc.day;
	atime->hour   = init_rtc.hour;
	atime->minute = init_rtc.minute;
	atime->second = init_rtc.second;	 
	atime->Wday   = WeekDayNum(init_rtc.year,init_rtc.month,init_rtc.day);
}
/*********************************************************************************************************************
函数名称: RTC_Read	         
功能描述: 	
输 入:   		
输 出:   	 	                 
*********************************************************************************************************************/
INT8S RTC_Read(RTC_INFOR* pdat)
{
	INT32U tmr_cnt = 0;

	// 获取RTC计数值
	tmr_cnt = HibernateRTCGet(); 
	
	acount_time_gap(pdat, tmr_cnt);
	
	return TRUE;
}
/*********************************************************************************************************************
函数名称: 	         
功能描述: 	
输 入:   		
输 出:   	 	                 
*********************************************************************************************************************/
INT8S RTC_Write(RTC_INFOR* pdat)
{	
	INT32U tmr_cnt = 0;
	INT8S err;
	
	tmr_cnt = time_acount_gap(*pdat, &err);
	// 设置RTC的值	 
	HibernateRTCSet(tmr_cnt);
	// 设置RTC0的匹配值
	HibernateRTCMatch0Set(HibernateRTCGet() + 5);
	
	return TRUE;
}
/*********************************************************************************************************************
函数名称: 	         
功能描述: 	
输 入:   		
输 出:   	 	                 
*********************************************************************************************************************/
#if 0
void HibernateHandler(void)
{
	INT32U ulStatus;

	ulStatus = HibernateIntStatus(1);
	// 清除休眠模块中断状态
	HibernateIntClear(ulStatus);

	if(ulStatus & HIBERNATE_INT_RTC_MATCH_0)
	{
		HibernateRTCMatch0Set(HibernateRTCGet() + 5);
	}
}
#endif
/*********************************************************************************************************************
函数名称: RTC_Init	         
功能描述: RTC模块初始化,在使用RTC之前需先调用	
输 入: NONE  		
输 出: 0 --> sucess  	 	                 
*********************************************************************************************************************/
INT8S RTC_Init(void)
{
	// 使能休眠模块
	SysCtlPeripheralEnable(SYSCTL_PERIPH_HIBERNATE);
	HibernateEnableExpClk(SysCtlClockGet());
	// 选择时钟源为4.194304MHz振荡器
	HibernateClockSelect(HIBERNATE_CLOCK_SEL_DIV128);
	// 设置冬眠模块RTC唤醒			
	HibernateWakeSet(HIBERNATE_WAKE_RTC);
	// 设置RTC的匹配值
	HibernateRTCMatch0Set(HibernateRTCGet() + 5);		
	// 使能RTC匹配0中断
//	HibernateIntEnable(HIBERNATE_INT_RTC_MATCH_0);
	// 清除所有中断状态
//	HibernateIntClear(HIBERNATE_INT_PIN_WAKE | HIBERNATE_INT_LOW_BAT |HIBERNATE_INT_RTC_MATCH_0 | HIBERNATE_INT_RTC_MATCH_1);
	// 注册中断句柄
//	HibernateIntRegister(HibernateHandler);
	// 使能RTC模块
	HibernateRTCEnable();
		
	HibernateRequest();

	return 0;
}
/*********************************************************************************************************************
                                                     end file
**********************************************************************************************************************/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -