PIC24FJ128GA010 Gerçek Zaman Saati Takvimi

Başlatan Gökhan BEKEN, 15 Ocak 2014, 12:03:07

Gökhan BEKEN

İlyas Karaca'ya teşekkürler...
kaynak: http://ilyaskaraca.com/gercek-zaman-saati-takvimi-pic24fj128ga010/

PIC24FJ128GA010 işlemcisi için rtc modülünün kullanımına ilişkin kodlarım aşağıdaki gibidir.

#include <p24fxxxx.h>
// Union to access rtcc registers
typedef union tagRTCC {
        struct {
                unsigned char sec;
                unsigned char min;
                unsigned char hr;
                unsigned char wkd;
                unsigned char day;
                unsigned char mth;
                unsigned char yr;
        };
        struct {
                unsigned int prt00;
                unsigned int prt01;
                unsigned int prt10;
                unsigned int prt11;
        };
} RTCC;
RTCC _time;
RTCC _time_chk;
RTCC _alarm;
// macro
#define mRTCCDec2Bin(Dec) (10*(Dec>>4)+(Dec&0x0f))
#define mRTCCBin2Dec(Bin) (((Bin/10)<<4)|(Bin%10))
unsigned char getHour(void);
unsigned char getMin(void);
unsigned char getSec(void);
unsigned char getMonth(void);
unsigned char getDay(void);
unsigned char getYear(void);
void RTCCgrab(void);
void RTCCInit(void);
void RTCCSet(void);
void RTCCAlarmSet(void);
void RTCCUnlock(void);
void RTCCSetBinSec(unsigned char, int);
void RTCCSetBinMin(unsigned char, int );
void RTCCSetBinHour(unsigned char, int );
void RTCCCalculateWeekDay(void);
void RTCCSetBinDay(unsigned char, int );
void RTCCSetBinMonth(unsigned char, int );
void RTCCSetBinYear(unsigned char, int );
unsigned char getHour(void) {
        return mRTCCDec2Bin(_time_chk.hr);
}
unsigned char getMin(void) {
        return mRTCCDec2Bin(_time_chk.min);
}
unsigned char getSec(void) {
        return mRTCCDec2Bin(_time_chk.sec);
}
unsigned char getMonth(void) {
        return mRTCCDec2Bin(_time_chk.mth);
}
unsigned char getDay(void) {
        return mRTCCDec2Bin(_time_chk.day);
}
unsigned char getYear(void) {
        return mRTCCDec2Bin(_time_chk.yr);
}
/*********************************************************************
 * Function: RTCCProcessEvents
 *
 * Preconditions: RTCCInit must be called before.
 *
 * Overview: The function grabs the current time from the RTCC and
 * translate it into strings.
 *
 * Input: None.
 *
 * Output: It update time and date strings  _time_str, _date_str,
 * and _time, _time_chk structures.
 *
 ********************************************************************/
void RTCCgrab(void)
{
        // Process time object only if time is not being set
                // Grab the time
                RCFGCALbits.RTCPTR = 0;
                _time.prt00 = RTCVAL;
                RCFGCALbits.RTCPTR = 1;
                _time.prt01 = RTCVAL;
                RCFGCALbits.RTCPTR = 2;
                _time.prt10 = RTCVAL;
                RCFGCALbits.RTCPTR = 3;
                _time.prt11 = RTCVAL;
                // Grab the time again
                RCFGCALbits.RTCPTR = 0;
                _time_chk.prt00 = RTCVAL;
                RCFGCALbits.RTCPTR = 1;
                _time_chk.prt01 = RTCVAL;
                RCFGCALbits.RTCPTR = 2;
                _time_chk.prt10 = RTCVAL;
                RCFGCALbits.RTCPTR = 3;
                _time_chk.prt11 = RTCVAL;
                // Verify there is no roll-over
                if ((_time.prt00 == _time_chk.prt00) &&
                        (_time.prt01 == _time_chk.prt01) &&
                        (_time.prt10 == _time_chk.prt10) &&
                        (_time.prt11 == _time_chk.prt11))
                {
                        // Here, you can watch structure _time,
                        //      which has the data from RTCC registers.
                        // TO DO: do something as you like here.
                }
}
/*********************************************************************
 * Function: RTCCInit
 *
 * Preconditions: RTCCInit must be called before.
 *
 * Overview: Enable the oscillator for the RTCC
 *
 * Input: None.
 *
 * Output: None.
 ********************************************************************/
void RTCCInit(void)
{
    // Enables the LP OSC for RTCC operation
        asm("mov #OSCCON,W1″);  // move address of OSCCON to W1
        asm("mov.b #0×02, W0″); // move 8-bit literal to W0, 16-bit.
        asm("mov.b #0×46, W2″); // unlock byte 1 for OSCCONL(low byte)
        asm("mov.b #0×57, W3″); // unlock byte 2 for OSCCONL(low byte)
                                                        // move 8-bit of Wn to OSCCON register
        asm("mov.b W2, [W1]");  // write unlock byte 1
        asm("mov.b W3, [W1]");  // write unlock byte 2
        asm("mov.b W0, [W1]");  // enable SOSCEN
    // Unlock sequence must take place for RTCEN to be written
        RCFGCAL = 0×0000;
    RTCCUnlock();
    RCFGCALbits.RTCEN = 1;      // bit15
//    RCFGCALbits.RTCOE = 1;    // bit10 enable output of alarm from rtcc
    // TO DO: Write the time and date to RTCC as follow.
        _time_chk.sec = 0×00;
        _time_chk.min = 0×58;
        _time_chk.hr = 0×23;
        _time_chk.wkd = 0×2;
        _time_chk.day = 0×31;
        _time_chk.mth = 0×12;
        _time_chk.yr = 0×08;
        RTCCCalculateWeekDay(); // To calculate and confirm the weekday
        // Set it after you change the time and date.
        RTCCSet();
}
/*********************************************************************
 * Function: RTCCSet
 *
 * Preconditions: None.
 *
 * Overview:
 * The function upload time and date from _time_chk into clock.
 *
 * Input: _time_chk – structure containing time and date.
 *
 * Output: None.
 *
 ********************************************************************/
void RTCCSet(void)
{
        RTCCUnlock();                           // Unlock the RTCC
        // Set the time
        RCFGCALbits.RTCPTR = 0;         // set min:sec
        RTCVAL = _time_chk.prt00;
        RCFGCALbits.RTCPTR = 1;         // set week:hour
        RTCVAL = _time_chk.prt01;
        RCFGCALbits.RTCPTR = 2;         // set month:day
        RTCVAL = _time_chk.prt10;
        RCFGCALbits.RTCPTR = 3;         // set year
        RTCVAL = _time_chk.prt11;
        RCFGCALbits.RTCWREN = 0;        // Lock the RTCC
        // Here, you can watch the RTCC register,
        //      the new time and date has been updated.
}
void RTCCAlarmSet(void)
{
        ALCFGRPTbits.ALRMEN = 0;                                // Disable the alarm
        // Set the time
        ALCFGRPTbits.ALRMPTR = 0;               // set min:sec
        ALRMVAL = _alarm.prt00;
        ALCFGRPTbits.ALRMPTR = 1;               // set week:hour
        RTCVAL = _alarm.prt01;
        ALCFGRPTbits.ALRMPTR = 2;               // set month:day
        RTCVAL = _alarm.prt10;
        ALCFGRPTbits.ALRMPTR = 3;               // set year
        RTCVAL = _alarm.prt11;
}
/*********************************************************************
 * Function: RTCCUnlock
 *
 * Preconditions: None.
 *
 * Overview: The function allows a writing into the clock registers.
 *
 * Input: None.
 *
 * Output: None.
 *
 ********************************************************************/
void RTCCUnlock()
{
        asm volatile("disi      #5″);
        asm volatile("mov #0×55, w7″);          // write 0×55 and 0xAA to
        asm volatile("mov w7, _NVMKEY");        //  NVMKEY to disable
        asm volatile("mov #0xAA, w8″);          //      write protection
        asm volatile("mov w8, _NVMKEY");
    asm volatile("bset _RCFGCAL, #13″); // set the RTCWREN bit
        asm volatile("nop");
        asm volatile("nop");
}
/*********************************************************************
 * Function: RTCCSetBinSec
 *
 * Preconditions: None.
 *
 * Overview: The function verifies setting seconds range, translates
 * it into BCD format and writes into _time_chk structure. To write
 * the structure into clock RTCCSet must be called.
 *
 * Input: Seconds binary value.
 *        int to indicate if this is for the alarm (1) or not(0)
 *
 * Output: Checked BCD value in _time_chk structure.
 *
 ********************************************************************/
void RTCCSetBinSec(unsigned char Sec, int forAlarm)
{
    if(Sec >= 60)  Sec = 0;
        if (forAlarm > 0) {
            _alarm.sec = mRTCCBin2Dec(Sec);
        } else {
            _time_chk.sec = mRTCCBin2Dec(Sec);
        }
}
/*********************************************************************
 * Function: RTCCSetBinMin
 *
 * Preconditions: None.
 *
 * Overview: The function verifies a setting minutes range, translates
 * it into BCD format and writes into _time_chk structure. To write
 * the structure into clock RTCCSet must be called.
 *
 * Input: Minutes binary value.
 *        int to indicate if this is for the alarm (1) or not(0)
 *
 * Output: Checked BCD value in _time_chk structure.
 *
 ********************************************************************/
void RTCCSetBinMin(unsigned char Min, int forAlarm)
{
    if(Min >= 60)  Min = 0;
        if (forAlarm > 0) {
            _alarm.min = mRTCCBin2Dec(Min);
        } else {
           _time_chk.min = mRTCCBin2Dec(Min);
        }
}
/*********************************************************************
 * Function: RTCCSetBinHour
 *
 * Preconditions: None.
 *
 * Overview: The function verifies a setting hours range, translates
 * it into BCD format and writes into _time_chk structure. To write
 * the structure into clock RTCCSet must be called.
 *
 * Input: Hours binary value.
 *        int to indicate if this is for the alarm (1) or not(0)
 *
 * Output: Checked BCD value in _time_chk structure.
 *
 ********************************************************************/
void RTCCSetBinHour(unsigned char Hour, int forAlarm)
{
    if(Hour >= 24) Hour = 0;
        if (forAlarm > 0) {
            _alarm.hr = mRTCCBin2Dec(Hour);
        } else {
            _time_chk.hr = mRTCCBin2Dec(Hour);
        }
}
/*********************************************************************
 * Function: RTCCCalculateWeekDay
 *
 * Preconditions:
 * Valid values of day, month and year must be presented in
 * _time_chk structure.
 *
 * Overview: The function reads day, month and year from _time_chk and
 * calculates week day. Than It writes result into _time_chk. To write
 * the structure into clock RTCCSet must be called.
 *
 * Input: _time_chk with valid values of day, month and year.
 *
 * Output: Zero based week day in _time_chk structure.
 *
 ********************************************************************/
void RTCCCalculateWeekDay()
{
        const char MonthOffset[] =
        //jan feb mar apr may jun jul aug sep oct nov dec
        {   0,  3,  3,  6,  1,  4,  6,  2,  5,  0,  3,  5 };
        unsigned Year;
        unsigned Month;
        unsigned Day;
        unsigned Offset;
    // calculate week day
    Year  = mRTCCDec2Bin(_time_chk.yr);
    Month = mRTCCDec2Bin(_time_chk.mth);
    Day  = mRTCCDec2Bin(_time_chk.day);
    // 2000s century offset = 6 +
    // every year 365%7 = 1 day shift +
    // every leap year adds 1 day
    Offset = 6 + Year + Year/4;
    // Add month offset from table
    Offset += MonthOffset[Month-1];
    // Add day
    Offset += Day;
    // If it's a leap year and before March there's no additional day yet
    if((Year%4) == 0)
        if(Month < 3)
            Offset -= 1;
    // Week day is
    Offset %= 7;
    _time_chk.wkd = Offset;
}
/*********************************************************************
 * Function: RTCCSetBinDay
 *
 * Preconditions: None.
 *
 * Overview: The function verifies a setting day range, translates it
 * into BCD format and writes into _time_chk structure. To write the
 * structure into clock RTCCSet must be called.
 *
 * Input: Day binary value.
 *        int to indicate if this is for the alarm (1) or not(0)
 *
 * Output: Checked BCD value in _time_chk structure.
 *
 ********************************************************************/
void RTCCSetBinDay(unsigned char Day, int forAlarm)
{
        const char MonthDaymax[] =
        //jan feb mar apr may jun jul aug sep oct nov dec
        {  31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
        unsigned Daymax;
        unsigned Month;
        unsigned Year;
    Month = mRTCCDec2Bin(_time_chk.mth);
    Year = mRTCCDec2Bin(_time_chk.yr);
    Daymax = MonthDaymax[Month-1];
    // February has one day more for a leap year
    if(Month == 2)
    if( (Year%4) == 0)
        Daymax++;
    if(Day == 0) Day = Daymax;
    if(Day > Daymax) Day = 1;
        if (forAlarm > 0) {
            _alarm.day = mRTCCBin2Dec(Day);
        } else {
            _time_chk.day = mRTCCBin2Dec(Day);
        }
}
/*********************************************************************
 * Function: RTCCSetBinMonth
 *
 * Preconditions: None.
 *
 * Overview: The function verifies a setting month range, translates
 * it into BCD format and writes into _time_chk structure. To write
 * the structure into clock RTCCSet must be called.
 *
 * Input: Month binary value.
 *        int to indicate if this is for the alarm (1) or not(0)
 *
 * Output: Checked BCD value in _time_chk structure.
 *
 ********************************************************************/
void RTCCSetBinMonth(unsigned char Month, int forAlarm)
{
    if(Month < 1) Month = 12;
    if(Month > 12) Month = 1;
        if (forAlarm > 0) {
            _alarm.mth = mRTCCBin2Dec(Month);
        } else {
            _time_chk.mth = mRTCCBin2Dec(Month);
        }
}
/*********************************************************************
 * Function: RTCCSetBinYear
 *
 * Preconditions: None.
 *
 * Overview: The function verifies a setting year range, translates it
 * into BCD format and writes into _time_chk structure. To write the
 * structure into clock RTCCSet must be called.
 *
 * Input: Year binary value.
 *        int to indicate if this is for the alarm (1) or not(0)
 *
 * Output: Checked BCD value in _time_chk structure.
 *
 ********************************************************************/
void RTCCSetBinYear(unsigned char Year, int forAlarm)
{
   if(Year >= 100)  Year = 0;
        if (forAlarm > 0) {
            _alarm.yr = mRTCCBin2Dec(Year);
        } else {
            _time_chk.yr = mRTCCBin2Dec(Year);
        }
    // Recheck day. Leap year influences to Feb 28/29.
    RTCCSetBinDay(mRTCCDec2Bin(_time_chk.day), forAlarm);
}
Özel mesaj okumuyorum, lütfen göndermeyin.