深入理解ARM體系架構(gòu)(S3C6410)---rtc實(shí)例
S2C6410中的閏年問題:
本文引用地址:http://www.ex-cimer.com/article/201611/317831.htm閏年產(chǎn)生器基于BCDDAY,BCDMOD,BCDYEAR從而能決定每月最后的日期是28,29,30,還是31。一個(gè)8位的計(jì)數(shù)器只能表示2個(gè)BCD數(shù)據(jù),因此不能判斷“00”結(jié)尾的年份是不是閏年。例如它不能判斷1900和2000是不是閏年。為了解決這個(gè)問題,S3C6410中有一硬件邏輯來支持2000的閏年問題。因此S3C6410支持1901到2099年的范圍。
讀寫操作:
在讀BCD寄存器時(shí),RTCCON寄存器0位必須至1,為了顯示秒,分,小時(shí),日,月,年,cpu必須從其對應(yīng)的寄存器中取值(BCDSEC, BCDMIN, BCDHOUR,BCDDATE, BCDDAY, BCDMON, BCDYEAR)。多寄存器同時(shí)讀取可能會(huì)產(chǎn)生1秒誤差。例如用戶從BCDMIN到BCDYEAR都進(jìn)行了讀,得到的結(jié)果為2059年12月31日23時(shí)59分,當(dāng)讀取這個(gè)結(jié)果時(shí)BCDSEC的數(shù)值在1~59之間,讀到的2059年12月31日23時(shí)59分是沒有問題的,但是當(dāng)讀取這個(gè)結(jié)果時(shí)BCDSEC的值為0,實(shí)際結(jié)果可能是2059年12月31日23時(shí)59分也可能是2060年1月1日0時(shí)0分。所以此時(shí)應(yīng)重讀這些寄存器,從而得到正確的數(shù)值。
后備電源操作:
實(shí)時(shí)時(shí)鐘邏輯能被后備電源驅(qū)動(dòng),通過RTCVDD向RTC模塊供電。當(dāng)系統(tǒng)關(guān)閉時(shí),cpu和RTC接口是封閉的,這時(shí)后備電源只驅(qū)動(dòng)振蕩電路和BCD計(jì)數(shù)器,從而把功耗降到最低。
邏輯圖:
接口:
以下程序完成了時(shí)間設(shè)置獲取,在lcd上顯示功能,
源碼如下
頭文件:
- //RTC
- #define
RTC_BASE (0x7E005040) - #define
rRTCCON (*(volatile unsigned *)RTC_BASE) - #define
rTICNT (*(volatile unsigned *)(RTC_BASE + 0x4)) - #define
rRTCALM (*(volatile unsigned *)(RTC_BASE + 0x10)) - #define
rALMSEC (*(volatile unsigned *)(RTC_BASE + 0x14)) - #define
rALMMIN (*(volatile unsigned *)(RTC_BASE + 0x18)) - #define
rALMHOUR (*(volatile unsigned *)(RTC_BASE + 0x1c)) - #define
rALMDATE (*(volatile unsigned *)(RTC_BASE + 0x20)) - #define
rALMMON (*(volatile unsigned *)(RTC_BASE + 0x24)) - #define
rALMYEAR (*(volatile unsigned *)(RTC_BASE + 0x28)) - #define
rBCDSEC (*(volatile unsigned *)(RTC_BASE + 0x30)) - #define
rBCDMIN (*(volatile unsigned *)(RTC_BASE + 0x34)) - #define
rBCDHOUR (*(volatile unsigned *)(RTC_BASE + 0x38)) - #define
rBCDDATE (*(volatile unsigned *)(RTC_BASE + 0x3c)) - #define
rBCDDAY (*(volatile unsigned *)(RTC_BASE + 0x40)) - #define
rBCDMON (*(volatile unsigned *)(RTC_BASE + 0x44)) - #define
rBCDYEAR (*(volatile unsigned *)(RTC_BASE + 0x48)) - #define
rCURTICNT (*(volatile unsigned *)(RTC_BASE + 0x50)) - #define
rINTP (*(volatile unsigned *)(RTC_BASE - 0x10))
- void
init_rtc() - {
rRTCCON = 0x85; - }
設(shè)置實(shí)時(shí)數(shù)據(jù):
- void
set_rtc() - {
- //2012,04.14.13,06
rRTCCON |= 0x01; rBCDSEC = 5*16 +1; rBCDMIN = 6; rBCDHOUR = 1*16 +3; rBCDDATE = 1*16+4; rBCDMON =4; rBCDYEAR = 1*16+2; rRTCCON &= ~(0x01); - }
獲取實(shí)時(shí)數(shù)據(jù):
- void
get_rtc(unsigned char rtc_data[6]) - {
rRTCCON |= 0x01; rtc_data[0] =rBCDSEC; rtc_data[1] = rBCDMIN; rtc_data[2] = rBCDHOUR; rtc_data[3] = rBCDDATE; rtc_data[4] = rBCDMON; rtc_data[5] = rBCDYEAR; rRTCCON &= ~(0x01); if(rtc_data[0] == 0) { rRTCCON |= 0x01; rtc_data[0] =rBCDSEC; rtc_data[1] = rBCDMIN; rtc_data[2] = rBCDHOUR; rtc_data[3] = rBCDDATE; rtc_data[4] = rBCDMON; rtc_data[5] = rBCDYEAR; rRTCCON &= ~(0x01); } - }
mian:
- init_rtc();
- LCD_Init();
- Paint_background(0xffffff,0,0,480,272);
- set_rtc();
- while(1)
- {
- get_rtc(tmp_rtc);
- rtc_data_tmp[13]
= tmp_rtc[0]; - rtc_data_tmp[12]
= tmp_rtc[0]/16; - rtc_data_tmp[11]
= tmp_rtc[1]; - rtc_data_tmp[10]
= tmp_rtc[1]/16; - rtc_data_tmp[9]
= tmp_rtc[2]; - rtc_data_tmp[8]
= tmp_rtc[2]/16; - rtc_data_tmp[7]
= tmp_rtc[3]; - rtc_data_tmp[6]
= tmp_rtc[3]/16; - rtc_data_tmp[5]
= tmp_rtc[4]; - rtc_data_tmp[4]
= tmp_rtc[4]/16; - rtc_data_tmp[3]
= tmp_rtc[5]; - rtc_data_tmp[2]
= tmp_rtc[5]/16; - rtc_data_tmp[1]
= tmp_rtc[6]; - rtc_data_tmp[0]
= tmp_rtc[6]/16; - for(jj=0;jj<14;jj++)
- {
Paint_text(124+8*jj, 20, 0x0,charnum[rtc_data_tmp[jj]],8, 16); - }
- delay_rtc();
- }
評論