RTC.H
/******************************************************************************/
/*This file is part of the uVision/ARM development tools*/
/*Copyright KEIL ELEKTRONIK GmbH 2002-2004*/
/******************************************************************************/
/**/
/*RTC.H:Header file for Real Time Clock (RTC)*/
/*Samsung S3C44B0X*/
/**/
/******************************************************************************/
#ifndef __RTC_H
#define __RTC_H
#define RTC_BASE0x01D70040// Real Time Clock Base Address
// Real Time Clock Registers
typedef struct {
reg8RTCCON;// RTC Control
reg8pad0[15];
reg8RTCALM;// RTC Alarm
reg8pad1[3];
reg8ALMSEC;// Alarm Second
reg8pad2[3];
reg8ALMMIN;// Alarm Minute
reg8pad3[3];
reg8ALMHOUR;// Alarm Hour
reg8pad4[3];
reg8ALMDAY;// Alarm Day
reg8pad5[3];
reg8ALMMON;// Alarm Month
reg8pad6[3];
reg8ALMYEAR;// Alarm Year
reg8pad7[3];
reg8RTCRST;// RTC Round Reset
reg8pad8[3];
reg8BCDSEC;// BCD Second
reg8pad9[3];
reg8BCDMIN;// BCD Minute
reg8padA[3];
reg8BCDHOUR;// BCD Hour
reg8padB[3];
reg8BCDDAY;// BCD Day
reg8padC[3];
reg8BCDDATE;// BCD Date
reg8padD[3];
reg8BCDMON;// BCD Month
reg8padE[3];
reg8BCDYEAR;// BCD Year
reg8padF[3];
reg8TICINT;// Tick Time Count
reg8padG[3];
} regRTC;
#define pRTC ((regRTC *)RTC_BASE)
// RTCCON: RTC Control Register
#define RTCEN0x00000001
#define CLKSEL0x00000002
#define CNTSEL0x00000004
#define CLKRST0x00000008
// RTCALM: RTC Alarm Register
#define SECEN0x00000001
#define MINEN0x00000002
#define HOUREN0x00000004
#define DAYEN0x00000008
#define MONREN0x00000010
#define YEAREN0x00000020
#define ALMEN0x00000040
// RTCRST: RTC Round Reset Register
#define SECCR_NONE0x00000000
#define SECCR_300x00000003
#define SECCR_400x00000004
#define SECCR_500x00000005
#define SRSTEN0x00000008
//*****************************************************
// TICNT: Tick Time Count Register
#define TICKINT_EN0x00000080
#ifndef __RTC_STRUCT_
#define __RTC_STRUCT_
//*****************************************************
//定义时间数据结构
//*****************************************************
typedef struct {
unsigned char Year; //采用BIN方法记录
unsigned char Mon;
unsigned char Day;
unsigned char Hour;
unsigned char Min;
unsigned char Sec;
unsigned char mS;
unsigned char Week;
}RTC_TIMER;
//***************************************************************************
//周期中断tick 10ms中断1次
//***************************************************************************
typedef struct{
unsigned int Tick;
unsigned char Fl200ms;
unsigned char Fl500ms;
unsigned char Fl1000ms;
unsigned char Divk[3];//记录TICK对应3个标志的取摸系数
}RTC_TICK;
//*****************************************************
extern void RTC_Timer_Init(void);
extern void RTC_Read_Timer(RTC_TIMER * p);
extern void RTC_Write_Timer(RTC_TIMER *p);
extern void RTC_Alarm_Init(RTC_TIMER *p);
extern void RTC_Tick_Init (void);
#endif
#endif /* __RTC_H */
#include "..\inc\44b.h"
#include "..\S3C44B0X_INC\S3C44B0X.H"
//*******************************************************************
RTC_TIMERSysTimer;
regRTC* const pRtc=pRTC;//定义RCT的指针
//*****************************************************
//定义初始化时间BIN
//*****************************************************
RTC_TIMER DefTimer={
6,//2006 06 10 08:20:50:00 6(week)
6,
10,
8,
20,
50,
0,
6,
};
//*******************************************************************
unsigned char BinToBCD (unsigned char i){
unsigned char bcd;
bcd=i/10;
bcd |=i%10;
return bcd;
}
//*******************************************************************
unsigned char BCDToBin (unsigned char bcd){
unsigned char i;
i=10*(bcd & 0xf0);
i+=bcd & 0x0f;
return i;
}
//*******************************************************************
//时间BIN<===>BCD
//*******************************************************************
void Turn_Bin_BCD (RTC_TIMER *pS,RTC_TIMER *pT){
pT->Year= BinToBCD(pS->Year);//2进制时间转化成BCD
pT->Mon= BinToBCD(pS->Mon);
pT->Day= BinToBCD(pS->Day);
pT->Hour= BinToBCD(pS->Hour);
pT->Min= BinToBCD(pS->Min);
pT->Sec= BinToBCD(pS->Sec);
pT->Week= BinToBCD(pS->Week);
}
//********************************************************************
//时间输入S3C44B0XRTC寄存器
//********************************************************************
void PutToRtc (RTC_TIMER *p){
pRtc->BCDYEAR = p->Year;
pRtc->BCDMON= p->Mon;
pRtc->BCDDAY= p->Day;// SUN:1 MON:2 TUE:3 WED:4 THU:5 FRI:6 SAT:7
pRtc->BCDDATE = p->Week;
pRtc->BCDHOUR = p->Hour;
pRtc->BCDMIN= p->Min;
pRtc->BCDSEC= p->Sec;
}
//*********************************************************************
//S3C44B0X RTC 初始化
//*********************************************************************
void RTC_Timer_Init(void){
/*CLKRST[3]RTC 时钟计数复位
0 = No reset, 1 = Reset
CNTSEL[2]BCD计数复位
0 = Merge BCD counters
1 = 保留 (Separate BCD counters)
CLKSEL[1]BCD 时钟选择
0 = XTAL 1/2 15 divided clock1Hz
1 = Reserved (XTAL clock only for test)
RTCEN[0]RTC读写允许
0 = Disable, 1 = Enable
*/
RTC_TIMER timer;
Turn_Bin_BCD (&timer,&DefTimer);
pRtc->RTCCON |= 0x01;// R/W enable, 1/32768, Normal(merge), No reset
PutToRtc(&timer);
pRtc->RTCCON &=~0x01;//禁止R/W
}
//*************************************************************************
//读取时间
//*************************************************************************
void RTC_Read_Timer(RTC_TIMER * p){
p->Year =BCDToBin( pRtc->BCDYEAR);
p->Mon=BCDToBin( pRtc->BCDMON);
p->Day=BCDToBin( pRtc->BCDDAY);
p->Week=BCDToBin( pRtc->BCDDATE);
p->Hour=BCDToBin( pRtc->BCDHOUR);
p->Min=BCDToBin( pRtc->BCDMIN);
p->Sec=BCDToBin( pRtc->BCDSEC);
}
//**************************************************************************
//写时间
//**************************************************************************
void RTC_Write_Timer(RTC_TIMER *p){
RTC_TIMER timer;
Turn_Bin_BCD (&timer,&SysTimer);
pRtc->RTCCON |= 0x01;// R/W enable, 1/32768, Normal(merge), No reset
PutToRtc(&timer);
pRtc->RTCCON &=~0x01;//禁止R/W
}
//********************************************************************************
//定时处理中断
//********************************************************************************
void __irq RTC_ISP_Alarm(void){
rI_ISPC=BIT_RTC;
//rI_ISPC; //is needed only when cache=on & wrbuf=on & BSFRD=0
//Uart_Printf("\nRTC Alarm Interrupt O.K.\n");
}
//*********************************************************************************
RTC_TIMER SysAlarm;
//*********************************************************************************
//定时时间初始化
//*********************************************************************************
void RTC_Alarm_Init(RTC_TIMER *p){
RTC_TIMER timer;
Turn_Bin_BCD (&timer,p);
pRtc->ALMYEAR=timer.Year;
pRtc->ALMMON =timer.Mon;
pRtc->ALMDAY =timer.Day;
pRtc->ALMHOUR=timer.Hour;
pRtc->ALMMIN =timer.Min;
pRtc->ALMSEC =timer.Sec;
pISR_RTC=(unsigned)RTC_ISP_Alarm;
//***********************************************************
//全部允许报警
//***********************************************************
pRtc->RTCALM=0x7f;//=1 打开 RTC ALARM CONTROL REGISTER (RTCALM)
//***********************************************************
rINTMSK=~(BIT_GLOBAL|BIT_RTC); //=0允许中断!
}
//*****************************************************************************
RTC_TICKRtcTick;//定义数据
//*****************************************************************************
//中断处理涵数
//*****************************************************************************
void __irq RTC_ISP_Tick(void){
rI_ISPC=BIT_TICK;
RtcTick.Tick++;
if(RtcTick.Tick % RtcTick.Divk[0]==0 ){
RtcTick.Fl200ms =~RtcTick.Fl200ms;
}
if(RtcTick.Tick % RtcTick.Divk[1]==0 ){
RtcTick.Fl500ms =~RtcTick.Fl500ms;
}
if(RtcTick.Tick % RtcTick.Divk[2]==0 ){
RtcTick.Fl1000ms =~RtcTick.Fl1000ms;
}
}
/*****************************************************************************
TICNT 计算10MS的分频系数 CLK=32768Hz 计算:Divk[3]
Period = ( n+1 ) / 128 second
n : Tick time count value (1-127)
如果要10ms中断==》n=1; 7.8ms中断一次
TICK INT ENABLE[7]时间滴答中断允许
0 = disable 1 = enable
TICK TIME COUNT[6:0]时间滴答计数值. (1-127)
这个计数值内部递减, 用户不能读它的实时值
******************************************************************************/
void RTC_Tick_Init (void){
pRtc->TICINT= 0x11; //打开 n=1
RtcTick.Divk[0]= 2*13;//k=200ms/(1000ms*(n+1)/128)
RtcTick.Divk[1]= 5*13;//k=200ms/(1000ms*(n+1)/128)
RtcTick.Divk[2]= 10*13;//k=200ms/(1000ms*(n+1)/128)
//***************************************************************
//pISR_TICK(*(unsigned *)(_ISR_STARTADDRESS+0x24))
// _ISR_STARTADDRESS+0x24 等于 Rtc_Tick 涵数的地址!
//***************************************************************
pISR_TICK=(unsigned)RTC_ISP_Tick;//中断向量地址转化
//*(unsigned *)(_ISR_STARTADDRESS+0x24)=(unsigned)Rtc_Tick;
//***************************************************************
rINTMSK=~(BIT_GLOBAL|BIT_TICK);
}