微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > PIC单片机RTCC时钟不对问题

PIC单片机RTCC时钟不对问题

时间:10-02 整理:3721RD 点击:
我用的是PIC24FJ128GA006   时钟老是比正常时间慢,我觉得是时钟配置,或者是晶振的问题,大婶们帮忙看看,谢了
#include "p24FJ128GA006.h"
_CONFIG1(JTAGEN_OFF & GCP_OFF & GWRP_OFF & COE_OFF & FWDTEN_OFF & ICS_PGx2)
_CONFIG2(FCKSM_CSDCMD & OSCIOFNC_OFF & POSCMOD_HS & FNOSC_SOSC)
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;
// macro
#define mRTCCDec2Bin(Dec) (10*(Dec>>4)+(Dec&0x0f))
#define mRTCCBin2Dec(Bin) (((Bin/10)<<4)|(Bin%10))
void RTCCgrab(void);
void RTCCInit(void);
void RTCCSet(void);
void RTCCUnlock(void);
void RTCCCalculateWeekDay(void);
void display(unsigned char x);
// main
int main(void)
{
    RTCCInit();                // initialization includes set the time and date
    while (1)
    {
    RTCCgrab();                // grab once
    display(_time_chk.sec);
    }
}
void display(unsigned char x)
{
    TRISE=0x00;
    LATE=x;
}
void RTCCgrab(void)
{
        // Process time object only if time is not being set
                // Grab the time
                RCFGCALbits.RTCPTR = 3;
                _time.prt11 = RTCVAL;
                _time.prt10 = RTCVAL;
                _time.prt01 = RTCVAL;
                _time.prt00 = RTCVAL;
                // Grab the time again
                RCFGCALbits.RTCPTR = 3;
                _time_chk.prt11 = RTCVAL;
                _time_chk.prt10 = RTCVAL;
                _time_chk.prt01 = RTCVAL;
                _time_chk.prt00 = 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.
                }
}
void RTCCInit(void)
{
    // Enables the LP OSC for RTCC operation
        asm("mov #OSCCON,W1");        // move address of OSCCON to W1
        asm("mov.b #0x02, W0");        // move 8-bit literal to W0, 16-bit.
        asm("mov.b #0x46, W2");        // unlock byte 1 for OSCCONL(low byte)
        asm("mov.b #0x57, 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        = 0x0000;
    RTCCUnlock();
    RCFGCALbits.RTCEN = 1;        // bit15
    //RTCC pin pad conected to RTCC second clock
        PADCFG1bits.RTSECSEL = 1;
        RCFGCALbits.RTCOE = 1;                //RTCC Output Enable bit
    // TO DO: Write the time and date to RTCC as follow.
        _time_chk.sec = 0x00;
        _time_chk.min = 0x05;
        _time_chk.hr = 0x7;
        _time_chk.wkd = 0x2;
        _time_chk.day = 0x24;
        _time_chk.mth = 0x07;
        _time_chk.yr = 0x07;
        RTCCCalculateWeekDay();        // To calculate and confirm the weekday
        // Set it after you change the time and date.
        RTCCSet();
}
void RTCCSet(void)
{
        RTCCUnlock();                                // Unlock the RTCC
        RCFGCALbits.RTCPTR = 3;                // Set the time
        RTCVAL = _time_chk.prt11;        // set year
        RTCVAL = _time_chk.prt10;        // set month:day
        RTCVAL = _time_chk.prt01;        // set week:hour
        RTCVAL = _time_chk.prt00;        // set min:sec
        RCFGCALbits.RTCWREN = 0;        // Lock the RTCC
}
void RTCCUnlock()
{
        asm volatile("disi        #5");
        asm volatile("mov #0x55, w7");                // write 0x55 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");
}
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;
}

有没有做过手册172页上说的 Calibration ?

2222222222222222222222222222222222222

唐辉电子,深耕晶振行业15年,非常专业,行业公认!
唐辉电子 官网上,有很多晶振使用、搭配、常见故障分析等方面的技术文档,欢迎分享。
真诚地希望和各位研发工程师长期互动、交友、携手进步。
32.768KHZ晶振,直插,贴片各种型号的,8M的,11.0592M,我司手里有现货,
少许样品,可免费给您。









Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top