S3C2440擁有一個實時時鐘模塊,可以在當系統(tǒng)電源關閉后通過備用電池工作。RTC可以通過使用STRB/LDRB ARM操作發(fā)送8位二-十進制交換碼(BCD)值數(shù)據(jù)給CPU。這些數(shù)據(jù)包括年、月、日、星期、時、分和秒的時間信息。RTC單元工作在外部32.768kHz晶振并且可以執(zhí)行鬧鐘功能
實時時鐘模塊保存的數(shù)據(jù)是DCD碼形式.
框圖如下
可以看到,要使用實時時鐘依靠以下幾個寄存器
包含時鐘使能和時鐘復位(還有兩個寄存器是測試模式,我們用不到)
關聯(lián)著時鐘節(jié)拍中斷,也就是每增加1S發(fā)生一次中斷
時鐘中斷,時鐘的時分秒年月日都是可以進行使能的
接下來是時分秒年月日鬧鐘點設置
有六個就不一一列舉了,意思是當?shù)竭_這個時間點時發(fā)生中斷,比如我設置23秒發(fā)生中斷,那么每一分鐘的23秒都會中斷一次
還要注意,因為使用的是BCD計數(shù),所以對時鐘的讀取,寫入都要進行BCD碼的轉(zhuǎn)換,否則數(shù)據(jù)不對哦
詳細查看代碼
#include"rtc.h"char*week_num[7]={"SUN","MON","TUES","WED","THURS","FRI","SAT"};RTC_TIMERrtcTimer;ALARM_TIMERalarmTimer;/**********************************TICK中斷**********************************/void__irqRTC_tickHandler(void){rSRCPND"=BIT_TICK;//清除源掛起rINTPND|=BIT_TICK;//清除中斷掛起RTCGetValue();printf("currentyear%dmouth%dday%dhour%dminute%dsec%drn",rtcTimer.year,rtcTimer.month,rtcTimer.day,rtcTimer.hour,rtcTimer.minute,rtcTimer.second);}/**********************************alarm鬧鐘中斷**********************************/void__irqRTC_alarmHandler(void){rSRCPND|=BIT_RTC;//清除源掛起rINTPND|=BIT_RTC;//清除中斷掛起printf("alarminthappendrn");}//rtc獲取時間voidRTCGetValue(void){u8temp=0,cover=0;rRTCCON|=0x01;//RTC讀寫使能,BCD時鐘、計數(shù)器、無復位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時鐘、計數(shù)器、無復位}voidRTCSetValue(void){u8temp;rRTCCON|=0x01;//RTC讀寫使能,BCD時鐘、計數(shù)器、無復位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時鐘、計數(shù)器、無復位}voidRtcSetAlarm(void){u8temp;rRTCCON|=0x01;//RTC讀寫使能,BCD時鐘、計數(shù)器、無復位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時鐘、計數(shù)器、無復位}voidRtcInit(u8tick){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;//中斷函數(shù)入口地址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"#defineYEAR_BASE2000typedefstructRTC_TIMER{u16year;u8month;u8day;u8weekDay;u8hour;u8minute;u8second;}RTC_TIMER;typedefstructALARM_TIMER{u16year;u8month;u8day;u8weekDay;u8hour;u8minute;u8second;}ALARM_TIMER;externstructRTC_TIMERrtcTimer;voidRTCGetValue(void);voidRTCSetValue(void);voidRtcSetAlarm(void);voidRtcInit(u8tick);#endif




