当系统电源关闭时,通过备用电源可以运行实时时钟(RTC)单元。数据包含的时间,即秒,分钟,小时,日期,日,月和年。RTC 工作由一个外部32.768kHz 的晶体驱动,并可以执行报警功能。
RTCCON 寄存器的位0 必须被设置为高位,为了是可以写入实时时钟模块中的BCD 寄存器,以显示秒,分钟,小时,日期,日,月和年。CPU 必须分别在RTC 模块的BCDSEC, BCDMIN, BCDHOUR, BCDDATE, BCDDAY,BCDMON 和 BCDYEAR 寄存器中读取数据。但是,因为多个寄存器被读取,所以可能有一秒的偏差存在。
寄存器:
参考程序:
#ifndef _S3C2451_RTC_H
#define _S3C2451_RTC_H
#include "typedef.h"
#include "s3c2451_irq.h"
typedef struct{
U32 RTCCON;
U32 TICNT0;
U32 TICNT2;
U32 TICNT1;
U32 RTCALM;
U32 ALMSEC;
U32 ALMMIN;
U32 ALMHOUR;
U32 ALMDATE;
U32 ALMMON;
U32 ALMYEAR;
U32 null;
U32 BCDSEC;
U32 BCDMIN;
U32 BCDHOUR;
U32 BCDDATE;
U32 BCDDAY;
U32 BCDMON;
U32 BCDYEAR;
U32 null1;
U32 TICKCNT;
}volatile* RTC_MemMapPtr;
#define RTC_BASE_PTR ((RTC_MemMapPtr)0x57000040)
typedef struct{
U16 second;
U16 minute;
U16 hour;
U16 day;
U16 date;
U16 month;
U16 year;
}RTC_Typedef;
extern void RTC_Interrupt_Init(U8 cnt, Functionalstate newstate);
extern void RTC_Set_Time(RTC_Typedef rtc_typedf);
extern void RTC_Get_Time(RTC_Typedef *rtc_typedf);
extern void TICK_IRQ_Init(U32 addr);
#endif
#include "s3c2451_rtc.h"
#include "s3c2451_vector.h"
/**函数名:RTC_Interrupt_Init
*参数:cnt newstate
*功能:初始化RTC
**/
void RTC_Interrupt_Init(U8 cnt, Functionalstate newstate)
{
if(newstate == ENABLE)
{
RTC_BASE_PTR->TICNT0 |= 0x80; //ENABLE
RTC_BASE_PTR->TICNT0 &= ~(0x7F); //清零
if(cnt > 127)
cnt = 127;
RTC_BASE_PTR->TICNT0 |= cnt; //设置滴答时间
}
else
{
RTC_BASE_PTR->TICNT0 &= ~(0x80); //DISABLE
}
}
/**函数名:RTC_Set_Time
*参数:rtc_typedf
*功能:设置时间
**/
void RTC_Set_Time(RTC_Typedef rtc_typedf)
{
RTC_BASE_PTR->RTCCON |= 1;
RTC_BASE_PTR->BCDYEAR = rtc_typedf.year;
RTC_BASE_PTR->BCDMON = rtc_typedf.month;
RTC_BASE_PTR->BCDDATE = rtc_typedf.date;
RTC_BASE_PTR->BCDDAY = rtc_typedf.day;
RTC_BASE_PTR->BCDHOUR = rtc_typedf.hour;
RTC_BASE_PTR->BCDMIN = rtc_typedf.minute;
RTC_BASE_PTR->BCDSEC = rtc_typedf.second;
RTC_BASE_PTR->RTCCON &= ~1;
}
/**函数名:RTC_Get_Time
*参数:rtc_typedf
*功能:获取时间
**/
void RTC_Get_Time(RTC_Typedef *rtc_typedf)
{
RTC_BASE_PTR->RTCCON |= 1;
rtc_typedf->year = 0x2000+RTC_BASE_PTR->BCDYEAR;
rtc_typedf->month = RTC_BASE_PTR->BCDMON;
rtc_typedf->date = RTC_BASE_PTR->BCDDATE; //日
rtc_typedf->day = RTC_BASE_PTR->BCDDATE; //周
rtc_typedf->hour = RTC_BASE_PTR->BCDHOUR;
rtc_typedf->minute = RTC_BASE_PTR->BCDMIN;
rtc_typedf->second = RTC_BASE_PTR->BCDSEC;
RTC_BASE_PTR->RTCCON &= ~1;
}
void TICK_IRQ_Init(U32 addr)
{
pISR_TICK = addr;
}
void __irq TICK_IRQ()
{
RTC_Typedef test;
char buf[30];
LCD_Clear(0xffffff);
RTC_Get_Time(&test);
sprintf(buf, "%4x-%02x-%02x %02x:%02x:%02x\r\n", test.year, test.month, test.day, test.hour, test.minute, test.second);
UART_printf(buf);
LCD_ShowString(80, 100, 180, 30, 16, (unsigned char*)buf);
IRQ_ClearSRCPND(INT_TICK);
}
#include "main.h"
extern const unsigned char hz[][32];
extern char buf[30];
void delay(volatile int count)
{
while (count--);
}
void delay_ms(unsigned int xms)
{
unsigned int j;
for(; xms > 0; xms--)
{
for(j = 500; j > 0; j --);
}
}
void Main(void)
{
RTC_Typedef rtc_typedf;
RTC_Interrupt_Init(64, ENABLE);
rtc_typedf.year = 0x17;
rtc_typedf.month = 0x7;
rtc_typedf.date = 0x23;
rtc_typedf.day = 0x5;
rtc_typedf.hour = 0x15;
rtc_typedf.minute = 0x38;
rtc_typedf.second = 0x30;
RTC_Set_Time(rtc_typedf);
IRQ_INTMSK_Init(INT_TICK, ENABLE);
TICK_IRQ_Init((U32)TICK_IRQ);
lcd_init();
LCD_Clear(0xffffff);
while(1)
{
// RTC_Get_Time(&test);
// sprintf(buf, "%4x-%x-%x %x:%x:%x\r\n", test.year, test.month, test.day, test.hour, test.minute, test.second);
// UART_printf(buf);
// LCD_ShowString(80, 100, 180, 30, 16, (unsigned char*)buf);
// LCD_Clear(0xffffff);
}
}