853728579 发表于 2014-3-26 11:49:33

PIC单片机内部时钟闹钟配置

本帖最后由 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;
    EnuWeekweek;
}StrTD, *pStrTD;

//update the repeat rate
# defineRTCC_AMASK_VALUE(x)                           (RtccSetAlarmRpt(x, TRUE))             //datasheet page229
//update the repeat count value
# defineRTCC_ALRMRPT_VALUE(y)                         (RtccSetAlarmRptCount(y, TRUE))   //datasheetpage230
//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 page229
    RTCC_ALRMRPT_VALUE(0xff);                               //datasheetpage230
    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;
      //产生闹钟中断
    }

}
页: [1]
查看完整版本: PIC单片机内部时钟闹钟配置