本帖最后由 853728579 于 2014-3-26 11:53 编辑
/*
* File: clock.h
* 本人用的核心板是: PIC18F26J50, XC8编译器
* PIC单片机内部时钟闹钟配置
* typedef unsigned char uchar;
* typedef unsigned int uint;
*
*
853728579@qq.com
* 2014年3月
*/
#ifndef CLOCK_H
#define CLOCK_H
#ifdef __cplusplus
extern "C" {
#endif
# include <p18f26j50.h>
# include <plib/rtcc.h>
# include "type.h"
typedef enum WeekInformation
{
Sum, Mon, Tue, Wed, Thurs, Fri, Sat
}EnuWeek;
typedef struct TimeInformation
{
uchar hour;
uchar min;
uchar second;
}StrTime, * pStrTime;
typedef struct DateInformation
{
uchar year;
uchar month;
uchar day;
}StrDate, * pStrDate;
typedef struct TimeDate
{
StrTime TimeSet;
StrDate DateSet;
EnuWeek week;
}StrTD, *pStrTD;
//update the repeat rate
# define RTCC_AMASK_VALUE(x) (RtccSetAlarmRpt(x, TRUE)) //datasheet page 229
//update the repeat count value
# define RTCC_ALRMRPT_VALUE(y) (RtccSetAlarmRptCount(y, TRUE)) //datasheet page 230
//mRtccAlrmEnable
#define RTCC_ALRM_ON() (ALRMCFGbits.ALRMEN=1)
//mRtccAlrmDisable
#define RTCC_ALRM_OFF() (ALRMCFGbits.ALRMEN=0)
//RTCC function
void RTCC_Initialize(StrTD const * pTime);
void RTCC_CountTime(void);
void RTCC_TimeSet(void);
void RTCC_UpdateTime(void);
void RTCC_WriteAlarmTime(void);
#ifdef __cplusplus
}
#endif
#endif /* CLOCK_H */
/*************************************************************************
* clock.c
**************************************************************************/
//Real-time clock
# include "clock.h"
//---Global structures used in deep sleep library---
rtccTimeDate RtccTimeDate ,RtccAlrmTimeDate;
rtccTimeDate Rtcc_read_TimeDate;
StrTD ReadTime;
StrTD gSetTime;
StrTD gAlrmTime;
/*************************************************************************
* Name: ClearProgressBar
* Parameters: uchar num
* Return Values: void
**************************************************************************/
void RTCC_Initialize(StrTD const * pTime)
{
RtccInitClock(); //turn on clock source
RtccWrOn(); //write enable the rtcc registers
RtccTimeDate.f.year = pTime->DateSet.year; //set year
RtccTimeDate.f.mon = pTime->DateSet.month; //Se month
RtccTimeDate.f.mday = pTime->DateSet.day; //Set day
RtccTimeDate.f.hour = pTime->TimeSet.hour; //Set Hour
RtccTimeDate.f.min = pTime->TimeSet.min; //Set minute
RtccTimeDate.f.sec = pTime->TimeSet.second; //Set second
RtccTimeDate.f.wday = pTime->week; //Set which day of the week forthe corrsponding date
RtccWriteTimeDate(&RtccTimeDate,1); //write into registers
//Alrm config
RTCC_WriteAlarmTime();
PIE3bits.RTCCIE = 1;
IPR3bits.RTCCIP = 0;
INTCONbits.GIEL = 1;
RTCCIF = 0;
RTCC_AMASK_VALUE(RTCC_RPT_MON); //datasheet page 229
RTCC_ALRMRPT_VALUE(0xff); //datasheet page 230
RtccSetChimeEnable(FALSE, TRUE);
mRtccOn(); //enable the rtcc
RTCC_ALRM_ON();
}
/*************************************************************************
* Name: RTCC_WriteAlarmTime
* Parameters: void
* Return Values: void
**************************************************************************/
void RTCC_WriteAlarmTime(void)
{
//RTCC config
# if 0
gAlrmTime.DateSet.month = 2;
gAlrmTime.DateSet.day = 2;
gAlrmTime.TimeSet.hour = 2;
gAlrmTime.TimeSet.min = 2;
gAlrmTime.TimeSet.second = 0;
gAlrmTime.week = 3;
# endif
RtccAlrmTimeDate.f.mon = gAlrmTime.DateSet.month /10*16 + gAlrmTime.DateSet.month %10; //Se month
RtccAlrmTimeDate.f.mday = gAlrmTime.DateSet.day /10*16 + gAlrmTime.DateSet.day %10; //Set day
RtccAlrmTimeDate.f.hour = gAlrmTime.TimeSet.hour /10*16 + gAlrmTime.TimeSet.hour %10; //Set Hour
RtccAlrmTimeDate.f.min = gAlrmTime.TimeSet.min /10*16 + gAlrmTime.TimeSet.min %10; //Set minute
RtccAlrmTimeDate.f.sec = gAlrmTime.TimeSet.second /10*16 + gAlrmTime.TimeSet.second %10; //Set second
RtccAlrmTimeDate.f.wday = gAlrmTime.week /10*16 + gAlrmTime.week %10;
RtccWriteAlrmTimeDate(&RtccAlrmTimeDate);
}
/*************************************************************************
* Name: RTCC_CountWeek
* Parameters: pStrDate pDate
* Return Values: uchar
**************************************************************************/
static void RTCC_CountWeek(StrDate const * pDate)
{
uint CountWeek = 0, CountYear = 0, CountDay = 0;
uint YearTemp;
YearTemp = pDate->year;
if (YearTemp <= 12)
CountYear = 0;
else if ((YearTemp>12) && (YearTemp<=16))
CountYear = YearTemp * 365 + 4;
else if ((YearTemp>16) && (YearTemp<=20))
CountYear = YearTemp * 365 + 5;
switch (pDate->month)
{
case 1: CountDay = pDate->day; break;
case 2: CountDay = 31 + pDate->day; break;
case 3: CountDay = 31 + 28 + pDate->day; break;
case 4: CountDay = 31 + 28 + 31 + pDate->day; break;
case 5: CountDay = 31 + 28 + 31 + 30 + pDate->day; break;
case 6: CountDay = 31 + 28 + 31 + 30 + 31 + pDate->day; break;
case 7: CountDay = 31 + 28 + 31 + 30 + 31 + 30 + pDate->day; break;
case 8: CountDay = 31 + 28 + 31 + 30 + 31 + 30 + 31 + pDate->day; break;
case 9: CountDay = 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + pDate->day; break;
case 10: CountDay = 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + pDate->day; break;
case 11: CountDay = 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + pDate->day; break;
case 12: CountDay = 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + pDate->day; break;
default: break;
}
if ((pDate->year%4==0) && (pDate->month>2))
CountDay = CountDay + 1;
else
CountDay = CountDay;
CountWeek = (CountYear+CountDay) % 7 + 5;
if (CountWeek < 8)
CountWeek = CountWeek;
else
CountWeek = CountWeek % 7;
if (CountWeek == 7)
CountWeek = 0;
ReadTime.week = CountWeek;
}
/*************************************************************************
* Name: RTCC_CountTime
* Parameters: void
* Return Values: void
**************************************************************************/
void RTCC_CountTime(void)
{
RtccReadTimeDate(&Rtcc_read_TimeDate); //Rtcc_read_TimeDate will have latest time
ReadTime.DateSet.year = Rtcc_read_TimeDate.f.year /16*10 + Rtcc_read_TimeDate.f.year %16;
ReadTime.DateSet.month = Rtcc_read_TimeDate.f.mon /16*10 + Rtcc_read_TimeDate.f.mon %16;
ReadTime.DateSet.day = Rtcc_read_TimeDate.f.mday /16*10 + Rtcc_read_TimeDate.f.mday %16;
ReadTime.TimeSet.hour = Rtcc_read_TimeDate.f.hour /16*10 + Rtcc_read_TimeDate.f.hour %16;
ReadTime.TimeSet.min = Rtcc_read_TimeDate.f.min /16*10 + Rtcc_read_TimeDate.f.min %16;
ReadTime.TimeSet.second = Rtcc_read_TimeDate.f.sec /16*10 + Rtcc_read_TimeDate.f.sec %16;
RTCC_CountWeek(&ReadTime.DateSet);
}
/*************************************************************************
* Name: RTCC_UpdateTime
* Parameters: void
* Return Values: void
**************************************************************************/
void RTCC_UpdateTime(void)
{
gSetTime.DateSet.year = gSetTime.DateSet.year / 10 * 16 + gSetTime.DateSet.year % 10;
gSetTime.DateSet.month = gSetTime.DateSet.month / 10 * 16 + gSetTime.DateSet.month % 10;
gSetTime.DateSet.day = gSetTime.DateSet.day / 10 * 16 + gSetTime.DateSet.day % 10;
gSetTime.TimeSet.hour = gSetTime.TimeSet.hour / 10 * 16 + gSetTime.TimeSet.hour % 10;
gSetTime.TimeSet.min = gSetTime.TimeSet.min / 10 * 16 + gSetTime.TimeSet.min % 10;
gSetTime.TimeSet.second = gSetTime.TimeSet.second / 10 * 16 + gSetTime.TimeSet.second% 10;
RTCC_Initialize(&gSetTime);
}
/*************************************************************************
* main.c
**************************************************************************/
# include <p18f26j50.h>
# include "clock.h"
extern StrTD ReadTime;
void main(void)
{
ReadTime.DateSet.year = 2;
ReadTime.DateSet.month = 2;
ReadTime.DateSet.day = 2;
ReadTime.TimeSet.hour = 2;
ReadTime.TimeSet.min = 1;
ReadTime.TimeSet.second = 30;
ReadTime.week = 0;
RTCC_Initialize(&ReadTime); //Configure RTCC using library APIs
RTCC_CountTime();
while (1)
{
RTCC_CountTime(); //读取后的数据存放在ReadTime变量中
}
}
void interrupt InterruptProgram(void)
{
if (RTCCIF == 1)
{
RTCCIF = 0;
//产生闹钟中断
}
}
一周热门 更多>