/****************************************************************************
* Copyright (C), 2013-2016, 沈阳连国科技电子有限公司
*
* 文件名: Internal_RTC.c
* 内容简述: STM32内部RTC驱动
*
* 文件历史:
* 版 本 号:V1.0
* 日 期:2013.9。17
* 作 者:IvanTang
* 说 明:
*
****************************************************************************/
//#include "stm32f10x_lib.h"
//#include <io.h>
#include "Internal_RTC.h"
//#include "stm32_i2c.h"
#include "stm32f10x_exti.h"
#include "stm32f10x_rcc.h"
#include "stm32f10x_rtc.h"
#include "stm32f10x_pwr.h"
//extern __IO uint16_t CurrentValue;
extern __IO uint32_t HiddenAddr;
extern __IO uint32_t IDAddr;
extern __IO uint32_t CRCBufAddr;
extern __IO uint32_t CpuID[];
extern __IO uint32_t FixedTime;
extern __IO uint16_t CurrentValue;
static u32 DayOfCurrentMonthNormal[] = {0,0,31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334};
static u32 DayOfCurrentMonthLeap[] = {0,0,31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335};
static u8 DayOfOneMonthValMAX[] = {0,31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
/****************************************************************************
* 函数名: ByteToPbcd
* 功 能: 将二进制数转换成BCD码.
* 输 入: 2进制数.
* 输 出: 无.
* 返 回: BCD码.
*/
u8 RTC_ByteToPbcd
(
u8 _ucHex /* 二进制数 */
)
{
return ((_ucHex / 10) << 4) + (_ucHex % 10);
}
/****************************************************************************
* 函数名: PbcdToByte
* 功 能: 将PBCD数据转换成HEX型数据.
* 输 入: bPbcd 待转换的PBCD数据.
* 输 出: 无.
* 返 回: u8 转换后的HEX数据.
*/
u8 RTC_PbcdToByte
(
u8 _ucPbcd /* 待转换的PBCD数据 */
)
{
return ((10 * (_ucPbcd >> 4)) + (_ucPbcd & 0x0f));
}
void Date_HexToBCD(RTC_T *_tRtc)
{
u8 val;
val = _tRtc->year % 100;
_tRtc->year /= 100;
_tRtc->year = (u16)(RTC_ByteToPbcd(_tRtc->year)&0x00ff);
_tRtc->year <<= 8;
_tRtc->year += (u16)(RTC_ByteToPbcd(val)&0x00ff);
_tRtc->month = RTC_ByteToPbcd(_tRtc->month);
_tRtc->day = RTC_ByteToPbcd(_tRtc->day);
_tRtc->hour = RTC_ByteToPbcd(_tRtc->hour);
_tRtc->minute = RTC_ByteToPbcd(_tRtc->minute);
_tRtc->second = RTC_ByteToPbcd(_tRtc->second);
}
void Date_BCDToHex(RTC_T *_tRtc)
{
u8 val;
val = _tRtc->year & 0x00ff;
_tRtc->year >>= 8;
_tRtc->year = (u16)(RTC_PbcdToByte(_tRtc->year)&0x00ff);
_tRtc->year *= 100;
_tRtc->year += (u16)(RTC_PbcdToByte(val)&0x00ff);
_tRtc->month = RTC_PbcdToByte(_tRtc->month);
_tRtc->day = RTC_PbcdToByte(_tRtc->day);
_tRtc->hour = RTC_PbcdToByte(_tRtc->hour);
_tRtc->minute = RTC_PbcdToByte(_tRtc->minute);
_tRtc->second = RTC_PbcdToByte(_tRtc->second);
}
/****************************************************************************
* 函数名: IsLeapYear
* 功 能: 判断时期时间是否有效
* 输 入: year :年.
* 输 出: 无.
* 返 回: TRUE表示闰年.
*/
static u8 IsRTCLeapYear (u16 year)
{
if (!(year%4) && (year%100) || !(year%400))
{
return TRUE;
}
else
{
return FALSE;
}
}
/****************************************************************************
* 函数名: IsValidDateTime
* 功 能: 判断时期时间是否有效
* 输 入: RTC_T 日期时间结构体
* 输 出: 无.
* 返 回: TRUE表示闰年.
*/
u8 IsRTCValidDateTime(RTC_T *_tRtc)
{
/* 年值不能超过 硬件RTC能够处理范围: 2001-2136 */
if(_tRtc->year < IRTC_YEAR_MIN || _tRtc->year > IRTC_YEAR_MAX)
{
return FALSE;
}
/* 日期不能大于指定的软件编译日期 */
if (_tRtc->year == IRTC_YEAR_MIN)
{
if (_tRtc->month < RTC_MONTH_MIN)
{
return FALSE;
}
else if(_tRtc->day < RTC_DAY_MIN)
{
return FALSE;
}
}
/* 检查月份 */
if((_tRtc->month < 1) || (_tRtc->month > 12))
{
return FALSE;
}
/* 检查day */
if((_tRtc->day < 1) || (_tRtc->day > 31))
{
return FALSE;
}
/* 判断大小月 */
if( _tRtc->day > DayOfOneMonthValMAX[_tRtc->month])
{
/* 闰年2月份为29天 */
if(_tRtc->month == 2)
{
if (IsRTCLeapYear( _tRtc->year))
{
if (_tRtc->day > 29 )
{
return FALSE;
}
}
else if (_tRtc->day > 28 )
{
return FALSE;
}
}
else
{
return FALSE;
}
}
/* 检查时分秒 */
if ((_tRtc->hour > 23) || (_tRtc->minute > 59) || (_tRtc->second > 59) )
{
return FALSE;
}
return TRUE;
}
u8 GetRTCWeek(RTC_T *_tRtc)
{
/*蔡勒(Zeller)公式: w=y+[y/4]+[c/4]-2c+[26(m+1)/10]+d-1
公式中的符号含义如下,w:星期;
c:世纪;
y:年(两位数);
m:月(m大于等于3,小于等于14,即在蔡勒公式中,
某年的1、2月要看作上一年的13、14月来计算,
比如2003年1月1日要看作2002年的13月1日来计算);
d:日;[ ]代表取整,即只要整数部分。*/
u8 y,c,m,d;
y = _tRtc->year % 100;
c = _tRtc->year /100;
m = _tRtc->month;
d = 1;
if(_tRtc->month < 3){
m += 12;
d++; //修正值,如果月份是13或14,需要多减去一个1
}
_tRtc->week = m + 1;
_tRtc->week *= 26;
_tRtc->week /= 10;
_tRtc->week += y;
_tRtc->week += y/4;
_tRtc->week += c/4;
_tRtc->week -= c<<1;
_tRtc->week += _tRtc->day;
_tRtc->week -= d;;
_tRtc->week %= 7;
return _tRtc->week;
}
/* 基于2001/1/1/00:00:00的日期计算秒时 */
uint32_t GetSecondFromDateTime(RTC_T *_tRtc)
{
u32 y,sec,fy,*ptr;
y = (u32)((_tRtc->year - (u16)RTC_BASE_YEAR)&0x0000FFFF);
fy = y / 4;
sec = fy * DAY_OF_FOURYEAR;
if(y/100){//百年不润
sec -= y/100;
}
if(y/400){//四百年再润
sec += y/400;
}
y %= 4;
sec += y * DAY_OF_YEAR;
ptr = DayOfCurrentMonthNormal;
if(y == 3 && _tRtc->month > 2 && IsRTCLeapYear(_tRtc->year)){//当前年为润年,并且月份已过2月,天数加1
ptr = DayOfCurrentMonthLeap;
}
sec += ptr[_tRtc->month];
sec += _tRtc->day - 1;
sec *= 24;
sec += _tRtc->hour;
sec *= 60;
sec += _tRtc->minute;
sec *= 60;
sec += _tRtc->second;
return sec;
}
/* 由秒时计算基�01/1/1/00:00:00的日期 */
void GetDateTimeFromSecond(u32 lSec, RTC_T *_tRtc)
{
uint16_t y,m;
u32 lDay,*ptr;
lDay = lSec / SECOND_OF_DAY; /* 转为基于天的时间 */
lSec = lSec % SECOND_OF_DAY;
_tRtc->year = RTC_BASE_YEAR;//基数年份
y = lDay / DAY_OF_FOURYEAR;
y *= 4;
_tRtc->year += y;
lDay %= DAY_OF_FOURYEAR;
if(y/100){//百年不润
lDay += y/100;
}
if(y/400){//四百年再润
lDay -= y/400;
}
y = lDay / DAY_OF_YEAR;
_tRtc->year += y; /* 得到年份 */
lDay %= DAY_OF_YEAR;
ptr = DayOfCurrentMonthNormal;
if(y == 3 && IsRTCLeapYear(_tRtc->year)){//当前年为润年,并且月份已过2月,天数加1
ptr = DayOfCurrentMonthLeap;
}
for(m=12;m>1;m--) /* 计算月份 */
{
if(lDay >= ptr[m]) {
lDay -= ptr[m];
break;
}
}
_tRtc->month = m;
_tRtc->day = lDay+1;
_tRtc->hour = lSec / SECOND_OF_HOUR;
lSec %= SECOND_OF_HOUR;
_tRtc->minute = lSec / SECOND_OF_MINUTE;
_tRtc->second = lSec % SECOND_OF_MINUTE;
lDay = GetSecondFromDateTime(_tRtc)/SECOND_OF_DAY;
//lDay++;
lDay %= 7;
lDay += RTC_BASE_WEEK;
_tRtc->week = lDay;
}
u8 SetConstantDurationAlarm(u8 *sbuf)
{
FixedTime = 0;
FixedTime = (uint32_t)(RTC_PbcdToByte(sbuf[1] & 0x7F) & 0x000000ff);
FixedTime *= 60;
FixedTime += (uint32_t)(RTC_PbcdToByte(sbuf[2] & 0x7F) & 0x000000ff);
FixedTime *= 60;
/* Wait until last write operation on RTC registers has finished */
RTC_WaitForLastTask();
/* Set the RTC Alarm */
RTC_SetAlarm(RTC_GetCounter()+FixedTime);
/* Wait until last write operation on RTC registers has finished */
RTC_WaitForLastTask();
return TRUE;
}
u8 SetDailyAlarm(u8 *sbuf)
{
u32 sec;
FixedTime = 0;
FixedTime = (uint32_t)(RTC_PbcdToByte(sbuf[1] & 0x7F) & 0x000000ff);
FixedTime *= 60;
FixedTime += (uint32_t)(RTC_PbcdToByte(sbuf[2] & 0x7F) & 0x000000ff);
FixedTime *= 60;
FixedTime += (uint32_t)(RTC_PbcdToByte(sbuf[3] & 0x7F) & 0x000000ff);
sec = RTC
由秒时钟计算日期的RTC程序
1星 需积分: 47 162 浏览量
2013-09-17
17:12:08
上传
评论
收藏 4KB RAR 举报
tangquanming
- 粉丝: 16
- 资源: 3
最新资源
- AIS2024 valid
- 最入门的爬虫代码 python.docx
- 爬虫零基础入门-爬取天气预报.pdf
- 最通俗易懂的 MongoDB 非结构化文档存储数据库教程.zip
- 以mongodb为数据库的订单物流小项目.zip
- 腾讯云-mongodb数据库, 项目部署.zip
- 腾讯 APIJSON 的 MongoDB 数据库插件.zip
- 理解非关系型数据库和关系型数据库的区别.zip
- 操作简单的Mongodb网页web管理工具,基于Spring Boot2.0支持mongodb集群.zip
- tms-mongodb-web,提供访问mongodb数据的REST API和可灵活扩展的mongodb web 客户端.zip
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈