S3C2440擁有一個(gè)實(shí)時(shí)時(shí)鐘模塊,可以在當(dāng)系統(tǒng)電源關(guān)閉后通過備用電池工作。RTC可以通過使用STRB/LDRB ARM操作發(fā)送8位二-十進(jìn)制交換碼(BCD)值數(shù)據(jù)給CPU。這些數(shù)據(jù)包括年、月、日、星期、時(shí)、分和秒的時(shí)間信息。RTC單元工作在外部32.768kHz晶振并且可以執(zhí)行鬧鐘功能
實(shí)時(shí)時(shí)鐘模塊保存的數(shù)據(jù)是DCD碼形式.
框圖如下
可以看到,要使用實(shí)時(shí)時(shí)鐘依靠以下幾個(gè)寄存器
包含時(shí)鐘使能和時(shí)鐘復(fù)位(還有兩個(gè)寄存器是測(cè)試模式,我們用不到)
關(guān)聯(lián)著時(shí)鐘節(jié)拍中斷,也就是每增加1S發(fā)生一次中斷
時(shí)鐘中斷,時(shí)鐘的時(shí)分秒年月日都是可以進(jìn)行使能的
接下來是時(shí)分秒年月日鬧鐘點(diǎn)設(shè)置
有六個(gè)就不一一列舉了,意思是當(dāng)?shù)竭_(dá)這個(gè)時(shí)間點(diǎn)時(shí)發(fā)生中斷,比如我設(shè)置23秒發(fā)生中斷,那么每一分鐘的23秒都會(huì)中斷一次
還要注意,因?yàn)槭褂玫氖荁CD計(jì)數(shù),所以對(duì)時(shí)鐘的讀取,寫入都要進(jìn)行BCD碼的轉(zhuǎn)換,否則數(shù)據(jù)不對(duì)哦
詳細(xì)查看代碼
#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獲取時(shí)間voidRTCGetValue(void){u8temp=0,cover=0;rRTCCON|=0x01;//RTC讀寫使能,BCD時(shí)鐘、計(jì)數(shù)器、無復(fù)位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í)鐘、計(jì)數(shù)器、無復(fù)位}voidRTCSetValue(void){u8temp;rRTCCON|=0x01;//RTC讀寫使能,BCD時(shí)鐘、計(jì)數(shù)器、無復(fù)位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í)鐘、計(jì)數(shù)器、無復(fù)位}voidRtcSetAlarm(void){u8temp;rRTCCON|=0x01;//RTC讀寫使能,BCD時(shí)鐘、計(jì)數(shù)器、無復(fù)位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鬧鐘控制寄存器,啟動(dòng)秒中斷和總中斷rRTCCON&=~(1<<0);//RTC讀寫禁止,BCD時(shí)鐘、計(jì)數(shù)器、無復(fù)位}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();//設(shè)置時(shí)間RtcSetAlarm();//設(shè)置鬧鐘//開啟中斷pISR_RTC=(unsigned)RTC_alarmHandler;pISR_TICK=(unsigned)RTC_tickHandler;//中斷函數(shù)入口地址rSRCPND|=BIT_RTC;//清除源掛起rINTPND|=BIT_RTC;//清除中斷掛起rINTMOD&=~BIT_RTC;//設(shè)置中斷模式為IRQ模式rSRCPND|=BIT_TICK;//清除源掛起rINTPND|=BIT_TICK;//清除中斷掛起rINTMOD&=~BIT_TICK;//設(shè)置中斷模式為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