深入理解ARM体系架构(S3C6410)---rtc实例

来源:互联网 发布:imap4_ssl 端口号 编辑:程序博客网 时间:2024/04/26 04:13

本系列文章由张同浩编写转载请注明出处:http://blog.csdn.net/muge0913/article/details/7460440

邮箱:muge0913@sina.com



实时时钟(RTC)的主要功能是在系统掉电的情况下,利用后备电源使时钟继续运行,从而不会丢失时间信息。s3c6410内部集成了RTC模块,其内部的寄存器BCDSEC,BCDMIN,BCDHOUR,BCDDAY,BCDDATE,BCDMON和BCDYEAR分别存储了当前的秒,分,小时,星期,日,月和年,表示时间的数值都是BCD码。

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上显示功能,

源码如下

头文件:

[cpp] view plaincopyprint?
  1. //RTC   
  2. #define RTC_BASE    (0x7E005040)   
  3. #define rRTCCON     (*(volatile unsigned *)RTC_BASE)  
  4. #define rTICNT      (*(volatile unsigned *)(RTC_BASE + 0x4))  
  5. #define rRTCALM     (*(volatile unsigned *)(RTC_BASE + 0x10))  
  6. #define rALMSEC     (*(volatile unsigned *)(RTC_BASE + 0x14))  
  7. #define rALMMIN     (*(volatile unsigned *)(RTC_BASE + 0x18))  
  8. #define rALMHOUR    (*(volatile unsigned *)(RTC_BASE + 0x1c))  
  9. #define rALMDATE    (*(volatile unsigned *)(RTC_BASE + 0x20))  
  10. #define rALMMON     (*(volatile unsigned *)(RTC_BASE + 0x24))  
  11. #define rALMYEAR    (*(volatile unsigned *)(RTC_BASE + 0x28))  
  12. #define rBCDSEC     (*(volatile unsigned *)(RTC_BASE + 0x30))  
  13. #define rBCDMIN     (*(volatile unsigned *)(RTC_BASE + 0x34))  
  14. #define rBCDHOUR    (*(volatile unsigned *)(RTC_BASE + 0x38))  
  15. #define rBCDDATE    (*(volatile unsigned *)(RTC_BASE + 0x3c))  
  16. #define rBCDDAY     (*(volatile unsigned *)(RTC_BASE + 0x40))  
  17. #define rBCDMON     (*(volatile unsigned *)(RTC_BASE + 0x44))  
  18. #define rBCDYEAR    (*(volatile unsigned *)(RTC_BASE + 0x48))  
  19. #define rCURTICNT   (*(volatile unsigned *)(RTC_BASE + 0x50))  
  20. #define rINTP       (*(volatile unsigned *)(RTC_BASE - 0x10))  



初始化rtc:

[cpp] view plaincopyprint?
  1. void init_rtc()  
  2. {  
  3.     rRTCCON = 0x85;  
  4. }  

设置实时数据:

[cpp] view plaincopyprint?
  1. void set_rtc()  
  2. {  
  3. //2012,04.14.13,06   
  4.     rRTCCON |= 0x01;  
  5.     rBCDSEC = 5*16 +1;  
  6.     rBCDMIN = 6;  
  7.     rBCDHOUR = 1*16 +3;  
  8.     rBCDDATE = 1*16+4;  
  9.     rBCDMON =4;  
  10.     rBCDYEAR = 1*16+2;  
  11.     rRTCCON &= ~(0x01);  
  12. }  

获取实时数据:

[cpp] view plaincopyprint?
  1. void get_rtc(unsigned char rtc_data[6])  
  2. {  
  3.   
  4.     rRTCCON |= 0x01;  
  5.     rtc_data[0] =rBCDSEC;  
  6.     rtc_data[1] = rBCDMIN;  
  7.     rtc_data[2] = rBCDHOUR;  
  8.     rtc_data[3] = rBCDDATE;  
  9.     rtc_data[4] = rBCDMON;  
  10.     rtc_data[5] = rBCDYEAR;  
  11.       
  12.     rRTCCON &= ~(0x01);   
  13.   
  14.     if(rtc_data[0] == 0)  
  15.     {  
  16.     rRTCCON |= 0x01;  
  17.     rtc_data[0] =rBCDSEC;  
  18.     rtc_data[1] = rBCDMIN;  
  19.     rtc_data[2] = rBCDHOUR;  
  20.     rtc_data[3] = rBCDDATE;  
  21.     rtc_data[4] = rBCDMON;  
  22.     rtc_data[5] = rBCDYEAR;   
  23.     rRTCCON &= ~(0x01);   
  24.     }  
  25.   
  26. }  



mian:

[cpp] view plaincopyprint?
  1. init_rtc();   
  2. LCD_Init();  
  3. Paint_background(0xffffff,0,0,480,272);  
  4. set_rtc();  
  5.   
  6. while(1)  
  7. {  
  8.   
  9. get_rtc(tmp_rtc);  
  10. rtc_data_tmp[13] = tmp_rtc[0]%16;  
  11. rtc_data_tmp[12] = tmp_rtc[0]/16;  
  12.   
  13. rtc_data_tmp[11] = tmp_rtc[1]%16;  
  14. rtc_data_tmp[10] = tmp_rtc[1]/16;  
  15.       
  16. rtc_data_tmp[9] = tmp_rtc[2]%16;  
  17. rtc_data_tmp[8] = tmp_rtc[2]/16;  
  18.   
  19. rtc_data_tmp[7] = tmp_rtc[3]%16;  
  20. rtc_data_tmp[6] = tmp_rtc[3]/16;  
  21.   
  22. rtc_data_tmp[5] = tmp_rtc[4]%16;  
  23. rtc_data_tmp[4] = tmp_rtc[4]/16;  
  24.       
  25. rtc_data_tmp[3] = tmp_rtc[5]%16;  
  26. rtc_data_tmp[2] = tmp_rtc[5]/16;  
  27.   
  28. rtc_data_tmp[1] = tmp_rtc[6]%16;  
  29. rtc_data_tmp[0] = tmp_rtc[6]/16;  
  30.   
  31. for(jj=0;jj<14;jj++)       
  32. {  
  33.     Paint_text(124+8*jj, 20, 0x0,charnum[rtc_data_tmp[jj]],8, 16);  
  34. }  
  35. delay_rtc();  
  36.   
  37. }  


程序下载地址:http://download.csdn.net/detail/muge0913/4225558

由于上传文件不及时显示,大家要程序的话,留下邮箱即可,