S3C2440的RTC解析

S3C2440拥有一个实时时钟模块, 可以在当系统电源关闭后通过备用电池工作。RTC可以通过使用STRB/LDRB ARM操作发送8位二-十进制交换码(BCD)值数据给CPU。这些数据包括年、月、日、星期、时、分和秒的时间信息。RTC单元工作在外部32.768kHz晶振并且可以执行闹钟功能

实时时钟模块保存的数据是DCD码形式.

框图如下


可以看到,要使用实时时钟依靠以下几个寄存器


包含时钟使能和时钟复位(还有两个寄存器是测试模式,我们用不到)


关联着时钟节拍中断,也就是每增加1S发生一次中断


时钟中断,时钟的时分秒年月日都是可以进行使能的

接下来是时分秒年月日闹钟点设置

有六个就不一一列举了,意思是当到达这个时间点时发生中断,比如我设置23秒发生中断,那么每一分钟的23秒都会中断一次

  还要注意,因为使用的是BCD计数,所以对时钟的读取,写入都要进行BCD码的转换,否则数据不对哦

  详细查看代码

 

#include "rtc.h"

char *week_num[7]={ "SUN","MON", "TUES", "WED", "THURS","FRI", "SAT" };


RTC_TIMER rtcTimer ;

ALARM_TIMER alarmTimer ;


/********************************
*
*	TICK中断
*
*********************************/
void __irq RTC_tickHandler(void)
{
	rSRCPND |= BIT_TICK;//清除源挂起
	rINTPND |= BIT_TICK;//清除中断挂起
	RTCGetValue();
	printf("current year %d mouth %d   day  %d    hour   %d  minute   %d sec   %d\r\n",rtcTimer.year,\
			rtcTimer.month,rtcTimer.day,rtcTimer.hour,rtcTimer.minute,rtcTimer.second);
} 

/********************************
*
*	alarm闹钟中断
*
*********************************/
void __irq RTC_alarmHandler(void)
{
	rSRCPND |= BIT_RTC;//清除源挂起
	rINTPND |= BIT_RTC;//清除中断挂起
	
	printf("alarm int happend\r\n");
}



//rtc获取时间
void RTCGetValue(void)
{
	u8 temp = 0,cover = 0;
	rRTCCON |= 0x01;	//RTC读写使能,BCD时钟、计数器、无复位
	temp = rBCDYEAR;
	temp = ((temp/16)*10)+(temp%16);
	rtcTimer.year = temp+YEAR_BASE;
	
	temp = rBCDMON;
	temp = ((temp/16)*10)+(temp%16);
	rtcTimer.month = temp;
	
	temp = rBCDDATE;
	temp = ((temp/16)*10)+(temp%16);
	rtcTimer.day = temp;
	
	temp = rBCDDAY;
	temp = ((temp/16)*10)+(temp%16);
	rtcTimer.weekDay = temp;
	
	temp = rBCDHOUR;
	temp = ((temp/16)*10)+(temp%16);
	rtcTimer.hour = temp;
	
	temp = rBCDMIN;
	temp = ((temp/16)*10)+(temp%16);
	rtcTimer.minute = temp;
	
	temp = rBCDSEC;
	temp = ((temp/16)*10)+(temp%16);
	rtcTimer.second = temp;
	
	rRTCCON &= ~(1<<0);	//RTC读写禁止,BCD时钟、计数器、无复位
}

void RTCSetValue(void)
{
	u8 temp;
	rRTCCON |= 0x01;	//RTC读写使能,BCD时钟、计数器、无复位
	
	temp = rtcTimer.year - YEAR_BASE;
	temp = ((temp/10)*16)+(temp%10);
	rBCDYEAR = temp;
	
	temp = rtcTimer.month;
	temp = ((temp/10)*16)+(temp%10);
	rBCDMON = temp;
	
	temp = rtcTimer.day;
	temp = ((temp/10)*16)+(temp%10);
	rBCDDATE = temp;
	
	temp = rtcTimer.weekDay;
	temp = ((temp/10)*16)+(temp%10);
	rBCDDAY = temp;
	
	temp = rtcTimer.hour;
	temp = ((temp/10)*16)+(temp%10);
	rBCDHOUR = temp;
	
	temp = rtcTimer.minute;
	temp = ((temp/10)*16)+(temp%10);
	rBCDMIN = temp;
	
	temp = rtcTimer.second;
	temp = ((temp/10)*16)+(temp%10);
	rBCDSEC = temp;
	
	rRTCCON &= ~(1<<0);	//RTC读写禁止,BCD时钟、计数器、无复位
}

void RtcSetAlarm(void)
{
	u8 temp;
	rRTCCON |= 0x01;	//RTC读写使能,BCD时钟、计数器、无复位
	
	temp = alarmTimer.year - YEAR_BASE;
	temp = ((temp/10)*16)+(temp%10);
	rALMYEAR = temp;
	
	temp = alarmTimer.month;
	temp = ((temp/10)*16)+(temp%10);
	rALMMON = temp;
	
	temp = alarmTimer.day;
	temp = ((temp/10)*16)+(temp%10);
	rALMDATE = temp;
	
	temp = alarmTimer.hour;
	temp = ((temp/10)*16)+(temp%10);
	rALMHOUR = temp;
	
	temp = alarmTimer.minute;
	temp = ((temp/10)*16)+(temp%10);
	rALMMIN = temp;
	
	temp = alarmTimer.second;
	temp = ((temp/10)*16)+(temp%10);
	rALMSEC = temp;
	
	rRTCALM = 0x41;		//RTC闹钟控制寄存器,启动秒中断和总中断
	
	rRTCCON &= ~(1<<0);	//RTC读写禁止,BCD时钟、计数器、无复位
}




void RtcInit(u8 tick)
{
	rtcTimer.year = 2014;
	rtcTimer.month = 10;
	rtcTimer.day = 10;
	rtcTimer.weekDay = 5;
	rtcTimer.hour = 16;
	rtcTimer.minute = 34;
	rtcTimer.second = 52;
	alarmTimer.year = 2014;
	alarmTimer.month = 10;
	alarmTimer.day = 10;
	alarmTimer.weekDay = 5;
	alarmTimer.hour = 16;
	alarmTimer.minute = 34;
	alarmTimer.second = 52;
	rRTCCON = 0x01;
	rTICNT=(tick&0x7f)|0x80;	//使能中断
	
	RTCSetValue();//设置时间
	RtcSetAlarm();//设置闹钟
	//开启中断
	pISR_RTC = (unsigned)RTC_alarmHandler;
	pISR_TICK=(unsigned)RTC_tickHandler;	//中断函数入口地址
	
	rSRCPND |= BIT_RTC;//清除源挂起
	rINTPND |= BIT_RTC;//清除中断挂起
	rINTMOD &= ~BIT_RTC;//设置中断模式为IRQ模式
	
	rSRCPND |= BIT_TICK;//清除源挂起
	rINTPND |= BIT_TICK;//清除中断挂起
	rINTMOD &= ~BIT_TICK;//设置中断模式为IRQ模式
	
	rINTMSK &= ~BIT_RTC; //开中断
	rINTMSK &= ~BIT_TICK; //开中断
	
}


 

#ifndef __RTC_H
#define __RTC_H
#include "2440addr.h"
#include "def.h"
#include "uart0.h"


#define YEAR_BASE 2000

typedef struct RTC_TIMER
{
	u16 year;
	u8 month;
	u8 day;
	u8 weekDay;
	u8 hour;
	u8 minute;
	u8 second;
}RTC_TIMER;

typedef struct ALARM_TIMER
{
	u16 year;
	u8 month;
	u8 day;
	u8 weekDay;
	u8 hour;
	u8 minute;
	u8 second;
}ALARM_TIMER;

extern struct RTC_TIMER rtcTimer;

void RTCGetValue(void);

void RTCSetValue(void);

void RtcSetAlarm(void);

void RtcInit(u8 tick);






#endif





 

posted @ 2014-10-10 22:02  邓小俊  阅读(659)  评论(0编辑  收藏  举报