S3C2440 裸机时钟RTC

   原文http://blog.csdn.net/z2200903505/article/details/7549556

    实时时钟(RTC)单元可以在当系统电源关闭后通过备用电池工作。RTC可以通过使用STRB/LDRB ARM操
作发送8位二-十进制交换码(BCD)值数据给CPU。这些数据包括年、月、日、星期、时、分和秒的时间信息。
RTC 单元工作在外部32.768kHz晶振并且可以执行闹钟功能。

RTC操作比较简单,寄存器的设置在数据手册上写的很详细,就不写了,贴一个RTC代码,该程序参考了天翔的RTC程序代码,主要是他写的比较好,都模块化了,我修改了他的代码,有闹钟(利用蜂鸣器),在TQ2440 板子上能运行,程序功能:串口每秒显示一次时间并且LED1闪一次,在闹钟设置中,秒为20时,显示闹钟时间并蜂鸣器发声几秒钟。

  1. #include "2440addr.h"   
  2. #include "Option.h"   
  3. #include "2440lib.h"   
  4. #include "def.h"   
  5.   
  6. #define  LED1_ON    (rGPBDAT &=~(1<<5))   
  7. #define  LED1_OFF   (rGPBDAT |=(1<<5) )   
  8.   
  9. void __irq RTC_tickHandler(void);  
  10. void __irq RTC_alarmHandler(void);  
  11.   
  12.   
  13. U8 alarmflag=0;  
  14.   
  15. typedef struct Date //定义一个表示日期时间的结构体   
  16.     {   U16 year;  
  17.         U8 month;  
  18.         U8 day;  
  19.         U8 week_day;  
  20.         U8 hour;  
  21.         U8 minute;  
  22.         U8 second;  
  23.     }date;  
  24.       
  25. date C_date;      
  26. char *week_num[7]={ "SUN","MON""TUES""WED""THURS","FRI""SAT" };//定义一个指针数组   
  27.   
  28. void Beep_Freq_Set( U32 freq )  
  29. {  
  30.   
  31.     rGPBCON &=~3;  
  32.     rGPBCON |=2;        //设置GPB0为OUT0   
  33.   
  34.     rGPBUP=0x0;     //使能上拉   
  35.   
  36.     rTCFG0 &=~0xff;  
  37.     rTCFG0 |=15;        //预分频值为15   
  38.       
  39.     rTCFG1 &=~0x0f;  
  40.     rTCFG1 |=0x02;  //分频值为8   
  41.       
  42.     rTCNTB0 = (PCLK>>7)/freq; //设定定时器0计数缓冲器的值      
  43.     rTCMPB0 = rTCNTB0>>1;     // 定时器0比较缓冲器的值,PWM输出占空比50%      
  44.     
  45.     rTCON &= ~0x1f;    
  46.     rTCON |= 0xb;   //自动重载,关闭变相,手动更新,开启定时器0      
  47.     rTCON &= ~2;            //清除手动更新位      
  48. }    
  49.     
  50. void Beep_Stop( void )    
  51. {    
  52.     rGPBCON &= ~3;          //set GPB0 as output      
  53.     rGPBCON |= 1;    
  54.     rGPBDAT &= ~1;       //输出低电平      
  55. }    
  56.   
  57. void delay(int x)  
  58. {  
  59.     int i,j;  
  60.     for(i=0;i<x;i++)  
  61.     for(j=0;j<1000000;j++);  
  62. }  
  63. /******************************** 
  64. * 
  65. *   设置实时时钟日期、 时间 
  66. * 
  67. *********************************/  
  68. void RTC_setdate(date *p_date)  
  69. {  
  70.     rRTCCON=0x01;   //RTC读写使能,BCD时钟、计数器、无复位   
  71.       
  72.     rBCDYEAR = p_date->year;  
  73.     rBCDMON = p_date->month;  
  74.     rBCDDATE = p_date->day;  
  75.     rBCDDAY = p_date->week_day;  //设置日期时间   
  76.     rBCDHOUR = p_date->hour;  
  77.     rBCDMIN = p_date->minute;  
  78.     rBCDSEC = p_date->second;  
  79.       
  80.     rRTCCON=0x00;   //RTC读写禁止,BCD时钟、计数器、无复位   
  81. }  
  82.   
  83. /******************************** 
  84. * 
  85. *   读取实时时钟日期、 时间 
  86. * 
  87. *********************************/  
  88. void RTC_getdate(date *p_date)  
  89. {  
  90.     rRTCCON=0x01;   //RTC读写使能,BCD时钟、计数器、无复位   
  91.           
  92.     p_date->year = rBCDYEAR+0x2000;  
  93.     p_date->month = rBCDMON;  
  94.     p_date->day = rBCDDATE;  
  95.     p_date->week_day = rBCDDAY;  //读取日期时间   
  96.     p_date->hour = rBCDHOUR;  
  97.     p_date->minute = rBCDMIN;  
  98.     p_date->second = rBCDSEC;      
  99.   
  100.     rRTCCON=0x00;   //RTC读写禁止,BCD时钟、计数器、无复位   
  101. }  
  102.   
  103. /******************************** 
  104. * 
  105. *   TICK中断初始化 
  106. * 
  107. *********************************/  
  108. void RTC_tickIRQ_Init(U8 tick)  
  109. {  
  110.     ClearPending(BIT_TICK); //清除标志位   
  111.     EnableIrq(BIT_TICK);    //使能中断源   
  112.       
  113.     pISR_TICK=(unsigned)RTC_tickHandler;    //中断函数入口地址   
  114.       
  115.     rRTCCON=0x00;  
  116.       
  117.     rTICNT=(tick&0x7f)|0x80;    //使能中断   
  118. }  
  119.   
  120. /******************************** 
  121. * 
  122. *   设置闹钟日期、 时间及其闹钟唤醒模式 
  123. * 
  124. *********************************/  
  125. void RTC_alarm_setdate(date *p_date,U8 mode)  
  126. {  
  127.     rRTCCON = 0x01;  
  128.       
  129.     rALMYEAR = p_date->year;  
  130.     rALMMON = p_date->month;  
  131.     rALMDATE = p_date->day;    
  132.     rALMHOUR = p_date->hour;  
  133.     rALMMIN = p_date->minute;  
  134.     rALMSEC = p_date->second;  
  135.     rRTCALM = mode;     //RTC闹钟控制寄存器   
  136.       
  137.     rRTCCON = 0x00;  
  138.       
  139.     ClearPending(BIT_RTC); //清除标志位                     
  140.     EnableIrq(BIT_RTC); //open RTC alarm  INTERRUPT   
  141.       
  142.     pISR_RTC = (unsigned)RTC_alarmHandler;  
  143. }  
  144.   
  145. void Main(void)  
  146. {  
  147.   
  148.     SelectFclk(2);  //设置系统时钟 400M        
  149.     ChangeClockDivider(2, 1);      //设置分频 1:4:8   
  150.     CalcBusClk();           //计算总线频率   
  151.       
  152.     rGPHCON &=~((3<<4)|(3<<6));     
  153.     rGPHCON |=(2<<4)|(2<<6);    //GPH2--TXD[0];GPH3--RXD[0]        
  154.     rGPHUP=0x00;        //使能上拉功能   
  155.           
  156.     Uart_Init(0,115200);  
  157.     Uart_Select(0);  
  158.       
  159.     rGPBCON &=~((3<<10)|(3<<12)|(3<<14)|(3<<16));   //对GPBCON[10:17]清零   
  160.     rGPBCON |=((1<<10)|(1<<12)|(1<<14)|(1<<16));    //设置GPB5~8为输出   
  161.     rGPBUP &=~((1<<5)|(1<<6)|(1<<7)|(1<<8));        //设置GPB5~8的上拉功能   
  162.     rGPBDAT |=(1<<5)|(1<<6)|(1<<7)|(1<<8);          //关闭LED   
  163.       
  164.     Beep_Stop();    //蜂鸣器停止发声,蜂鸣器用作闹钟声   
  165.       
  166.     C_date.year = 0x12;  
  167.     C_date.month = 0x05;  
  168.     C_date.day = 0x09;  
  169.     C_date.week_day = 0x03; //设置当前日期时间   
  170.     C_date.hour = 0x12;  
  171.     C_date.minute = 0x00;  
  172.     C_date.second = 0x10;     
  173.       
  174.     RTC_setdate(&C_date);  
  175.       
  176.     C_date.second=0x20;  
  177.       
  178.     RTC_alarm_setdate(&C_date,0x41);//0x41表示使能RTC闹钟,以及使能秒时钟闹钟   
  179.       
  180.     RTC_tickIRQ_Init(127);          // 设置1秒钟tick一次   
  181.       
  182.       
  183.     Uart_Printf("\n ---实时时钟测试程序---\n");  
  184.     while(Uart_GetKey()!= ESC_KEY)  
  185.     {  
  186.         LED1_OFF;  
  187.         RTC_getdate(&C_date);  
  188.         if(alarmflag)  
  189.         {  
  190.             alarmflag=0;  
  191.           
  192.             Uart_Printf("\nRTC ALARM  %02x:%02x:%02x \n",C_date.hour,C_date.minute,C_date.second);  
  193.             Beep_Freq_Set(1000);  
  194.             delay(5);  
  195.             Beep_Stop();  
  196.         }  
  197.     }  
  198.   
  199. }  
  200.   
  201. /******************************** 
  202. * 
  203. *   TICK中断 
  204. * 
  205. *********************************/  
  206. void __irq RTC_tickHandler(void)  
  207. {  
  208.     ClearPending(BIT_TICK);  
  209.     LED1_ON;   //刷新LED1   
  210.     Delay(500);  
  211.     RTC_getdate(&C_date);  
  212.     Uart_Printf("RTC TIME: %04x-%02x-%02x  %s %02x:%02x:%02x\n", C_date.year,C_date.month,C_date.day,week_num[C_date.week_day], C_date.hour, C_date.minute, C_date.second );  
  213.       
  214. }   
  215.   
  216. /******************************** 
  217. * 
  218. *   TICK中断 
  219. * 
  220. *********************************/  
  221. void __irq RTC_alarmHandler(void)  
  222. {  
  223.    alarmflag = 1;  
  224.    ClearPending(BIT_RTC);  
  225. }  
#include "2440addr.h"
#include "Option.h"
#include "2440lib.h"
#include "def.h"

#define  LED1_ON	(rGPBDAT &=~(1<<5))
#define  LED1_OFF	(rGPBDAT |=(1<<5) )

void __irq RTC_tickHandler(void);
void __irq RTC_alarmHandler(void);


U8 alarmflag=0;

typedef struct Date	//定义一个表示日期时间的结构体
	{	U16 year;
		U8 month;
		U8 day;
		U8 week_day;
		U8 hour;
		U8 minute;
		U8 second;
	}date;
	
date C_date;	
char *week_num[7]={ "SUN","MON", "TUES", "WED", "THURS","FRI", "SAT" };//定义一个指针数组

void Beep_Freq_Set( U32 freq )
{

	rGPBCON &=~3;
	rGPBCON |=2;		//设置GPB0为OUT0

	rGPBUP=0x0;		//使能上拉

	rTCFG0 &=~0xff;
	rTCFG0 |=15;		//预分频值为15
	
	rTCFG1 &=~0x0f;
	rTCFG1 |=0x02;	//分频值为8
	
    rTCNTB0 = (PCLK>>7)/freq; //设定定时器0计数缓冲器的值   
    rTCMPB0 = rTCNTB0>>1;     // 定时器0比较缓冲器的值,PWM输出占空比50%   
  
    rTCON &= ~0x1f;  
    rTCON |= 0xb;   //自动重载,关闭变相,手动更新,开启定时器0   
    rTCON &= ~2;            //清除手动更新位   
}  
  
void Beep_Stop( void )  
{  
    rGPBCON &= ~3;          //set GPB0 as output   
    rGPBCON |= 1;  
    rGPBDAT &= ~1;       //输出低电平   
}  

void delay(int x)
{
	int i,j;
	for(i=0;i<x;i++)
	for(j=0;j<1000000;j++);
}
/********************************
*
*	设置实时时钟日期、 时间
*
*********************************/
void RTC_setdate(date *p_date)
{
	rRTCCON=0x01;	//RTC读写使能,BCD时钟、计数器、无复位
	
	rBCDYEAR = p_date->year;
	rBCDMON = p_date->month;
	rBCDDATE = p_date->day;
	rBCDDAY = p_date->week_day;	//设置日期时间
	rBCDHOUR = p_date->hour;
	rBCDMIN = p_date->minute;
	rBCDSEC = p_date->second;
	
	rRTCCON=0x00;	//RTC读写禁止,BCD时钟、计数器、无复位
}

/********************************
*
*	读取实时时钟日期、 时间
*
*********************************/
void RTC_getdate(date *p_date)
{
	rRTCCON=0x01;	//RTC读写使能,BCD时钟、计数器、无复位
		
	p_date->year = rBCDYEAR+0x2000;
	p_date->month = rBCDMON;
	p_date->day = rBCDDATE;
	p_date->week_day = rBCDDAY;	//读取日期时间
	p_date->hour = rBCDHOUR;
	p_date->minute = rBCDMIN;
	p_date->second = rBCDSEC;	

	rRTCCON=0x00;	//RTC读写禁止,BCD时钟、计数器、无复位
}

/********************************
*
*	TICK中断初始化
*
*********************************/
void RTC_tickIRQ_Init(U8 tick)
{
	ClearPending(BIT_TICK); //清除标志位
	EnableIrq(BIT_TICK);	//使能中断源
	
	pISR_TICK=(unsigned)RTC_tickHandler;	//中断函数入口地址
	
	rRTCCON=0x00;
	
	rTICNT=(tick&0x7f)|0x80;	//使能中断
}

/********************************
*
*	设置闹钟日期、 时间及其闹钟唤醒模式
*
*********************************/
void RTC_alarm_setdate(date *p_date,U8 mode)
{
	rRTCCON = 0x01;
	
	rALMYEAR = p_date->year;
	rALMMON = p_date->month;
	rALMDATE = p_date->day;	
	rALMHOUR = p_date->hour;
	rALMMIN = p_date->minute;
	rALMSEC = p_date->second;
	rRTCALM = mode;		//RTC闹钟控制寄存器
	
	rRTCCON = 0x00;
	
	ClearPending(BIT_RTC); //清除标志位                	
    EnableIrq(BIT_RTC); //open RTC alarm  INTERRUPT
    
    pISR_RTC = (unsigned)RTC_alarmHandler;
}

void Main(void)
{

	SelectFclk(2);  //设置系统时钟 400M     
	ChangeClockDivider(2, 1);      //设置分频 1:4:8
	CalcBusClk();           //计算总线频率
	
	rGPHCON &=~((3<<4)|(3<<6));   
    rGPHCON |=(2<<4)|(2<<6);    //GPH2--TXD[0];GPH3--RXD[0]     
    rGPHUP=0x00;        //使能上拉功能
    	
    Uart_Init(0,115200);
    Uart_Select(0);
    
	rGPBCON &=~((3<<10)|(3<<12)|(3<<14)|(3<<16));	//对GPBCON[10:17]清零
	rGPBCON |=((1<<10)|(1<<12)|(1<<14)|(1<<16));	//设置GPB5~8为输出
	rGPBUP &=~((1<<5)|(1<<6)|(1<<7)|(1<<8));		//设置GPB5~8的上拉功能
	rGPBDAT |=(1<<5)|(1<<6)|(1<<7)|(1<<8);			//关闭LED
	
	Beep_Stop();	//蜂鸣器停止发声,蜂鸣器用作闹钟声
	
	C_date.year = 0x12;
	C_date.month = 0x05;
	C_date.day = 0x09;
	C_date.week_day = 0x03;	//设置当前日期时间
	C_date.hour = 0x12;
	C_date.minute = 0x00;
	C_date.second = 0x10;	
	
	RTC_setdate(&C_date);
	
	C_date.second=0x20;
	
	RTC_alarm_setdate(&C_date,0x41);//0x41表示使能RTC闹钟,以及使能秒时钟闹钟
	
	RTC_tickIRQ_Init(127);          // 设置1秒钟tick一次
	
	
 	Uart_Printf("\n ---实时时钟测试程序---\n");
	while(Uart_GetKey()!= ESC_KEY)
	{
		LED1_OFF;
		RTC_getdate(&C_date);
		if(alarmflag)
		{
			alarmflag=0;
		
			Uart_Printf("\nRTC ALARM  %02x:%02x:%02x \n",C_date.hour,C_date.minute,C_date.second);
			Beep_Freq_Set(1000);
			delay(5);
			Beep_Stop();
		}
	}

}

/********************************
*
*	TICK中断
*
*********************************/
void __irq RTC_tickHandler(void)
{
	ClearPending(BIT_TICK);
    LED1_ON;   //刷新LED1
    Delay(500);
    RTC_getdate(&C_date);
	Uart_Printf("RTC TIME: %04x-%02x-%02x  %s %02x:%02x:%02x\n", C_date.year,C_date.month,C_date.day,week_num[C_date.week_day], C_date.hour, C_date.minute, C_date.second );
    
} 

/********************************
*
*	TICK中断
*
*********************************/
void __irq RTC_alarmHandler(void)
{
   alarmflag = 1;
   ClearPending(BIT_RTC);
}


 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值