pic单片机内部时钟校准c语言,PIC单片机RTCC时钟不对问题

我用的是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;

}

我用的是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;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值