S2C6410中的闰年问题:
闰年产生器基于BCDDAY,BCDMOD,BCDYEAR从而能决定每月最后的日期是28,29,30,还是31。一个8位的计数器只能表示2个BCD数据,因此不能判断“00”结尾的年份是不是闰年。例如它不能判断1900和2000是不是闰年。为了解决这个问题,S3C6410中有一硬件逻辑来支持2000的闰年问题。因此S3C6410支持1901到2099年的范围。
读写操作:
在读BCD寄存器时,RTCCON寄存器0位必须至1,为了显示秒,分,小时,日,月,年,cpu必须从其对应的寄存器中取值(BCDSEC, BCDMIN, BCDHOUR,BCDDATE, BCDDAY, BCDMON, BCDYEAR)。多寄存器同时读取可能会产生1秒误差。例如用户从BCDMIN到BCDYEAR都进行了读,得到的结果为2059年12月31日23时59分,当读取这个结果时BCDSEC的数值在1~59之间,读到的2059年12月31日23时59分是没有问题的,但是当读取这个结果时BCDSEC的值为0,实际结果可能是2059年12月31日23时59分也可能是2060年1月1日0时0分。所以此时应重读这些寄存器,从而得到正确的数值。
后备电源操作:
实时时钟逻辑能被后备电源驱动,通过RTCVDD向RTC模块供电。当系统关闭时,cpu和RTC接口是封闭的,这时后备电源只驱动振荡电路和BCD计数器,从而把功耗降到最低。
逻辑图:
接口:
以下程序完成了时间设置获取,在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))
初始化rtc:
- void
init_rtc() - {
-
rRTCCON = 0x85; - }
设置实时数据:
- 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); - }
获取实时数据:
- 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();
-
- }
上一篇:arm linux 下中断流程简要分析注册中断
下一篇:深入理解ARM体系架构(S3C6410)---ad转化实例
推荐阅读最新更新时间:2024-03-16 14:58