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

本系列文章由张同浩编写转载请注明出处: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上显示功能,

源码如下

头文件:

  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
#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:

  1. void init_rtc()  
  2. {  
  3.     rRTCCON = 0x85;  
  4. }  
void init_rtc()
{
	rRTCCON = 0x85;
}

设置实时数据:

  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. }  
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);
}

获取实时数据:

  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. }  
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:

  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. }  
	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]%16;
	rtc_data_tmp[12] = tmp_rtc[0]/16;
	
	rtc_data_tmp[11] = tmp_rtc[1]%16;
	rtc_data_tmp[10] = tmp_rtc[1]/16;
		
	rtc_data_tmp[9] = tmp_rtc[2]%16;
	rtc_data_tmp[8] = tmp_rtc[2]/16;
	
	rtc_data_tmp[7] = tmp_rtc[3]%16;
	rtc_data_tmp[6] = tmp_rtc[3]/16;
	
	rtc_data_tmp[5] = tmp_rtc[4]%16;
	rtc_data_tmp[4] = tmp_rtc[4]/16;
		
	rtc_data_tmp[3] = tmp_rtc[5]%16;
	rtc_data_tmp[2] = tmp_rtc[5]/16;
	
	rtc_data_tmp[1] = tmp_rtc[6]%16;
	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();
	
	}


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

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值