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;
}
#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,我司手里有现货,
少许样品,可免费给您。