基于mini2440的RTC读写(裸机)

很多处理器都有RTC实时时钟功能,s3c2440也提供了这个功能,其功能主要是:实时时钟、闹钟、tick中断等。RTC的操作比较简单。读写时RTCCON最低位应设置为1,不读写时设置为0以免误修改RTC相应寄存器。

BCDSEC,BCDMIN,BCDHOUR,BCDDAY,BCDDATE,BCDMON,BCDYEAR可以设置和读取RTC的值,在编程中需要注意一秒只差的问题(具体可查看芯片手册),所以在BCDSEC值为0时需要重新读取RTC相应寄存器,防止误差,这点需要特别注意。

tick中断可为RTOS提供中断时钟,其周期计算如下:


可在TICNT设置相应位。达到周期产生中断。

闹钟功能在RTCALM允许使能。在ALMSEC、ALMMIN、ALMHOUR、ALMDATE、ALMMON、ALMYEAR中设置闹钟值,到达时间后产生相应中断。

还有一点需要注意,s3c2440的RTC以BCD码进行读写,所以要以十进制操作应做相应转换。RTC操作比较简单,这里不再作详细介绍,具体可查看芯片手册。测试:将相应时间写入RTC、设置相应tick中断和闹钟。通过串口显示相应时间。

代码如下:

main.c部分

#define  GLOBAL_CLK 1

#include<string.h>
#include "def.h"
#include "option.h"
#include "2440addr.h"
#include "profile.h"
#include "mmu.h"

extern void RTC_Set(char year, char month, char week,
			char date, char hour, char min, char sec);
extern void RTC_Read(char *year, char *month, char *week,
			char *date, char *hour, char *min, char *sec);
extern void RTC_Alarm_Set(char year, char mon, char date,
			char hour, char min, char sec);
extern void RTC_Init(void);
extern void RTC_Tick(void);
extern void RTC_Alarm(void);

extern char tick_flag, alarm_flag;
void delay(int num);

void delay(int num)
{
	int i, j, k;
	for(i=0;i<num;i++)
		for(j=0;j<1000;j++)
			for(k=0;k<1000;k++);
}

void Main(void)
{
	char data[7] = {0};
	char *week_str[7] = {"Mon", "Tue", "Wed", 
						"Thu", "Fri", "Sat", "Sun"};
	char *week;
	int count = 0;
	
	rGPBCON=(1<<0);
    rGPBDAT=(0<<0);//关闭蜂鸣器
	
	MMU_Init();//地址的重映射
	RTC_Init();
	RTC_Tick();
	RTC_Alarm();
	
	RTC_Set(13, 9, 6, 7, 19, 59, 12);
	RTC_Alarm_Set(13, 9, 7, 20, 0, 0);
	
	while ( 1 ){
		RTC_Read(&data[0], &data[1], &data[2], 
			&data[3], &data[4], &data[5], &data[6]);
		
		switch ( data[2]){
			case 1 : week = week_str[0] ;
					break;
			case 2 : week = week_str[1];
					break;
			case 3 : week = week_str[2];
					break;
			case 4 : week = week_str[3];
					break;
			case 5 : week = week_str[4];
					break;
			case 6 : week = week_str[5];
					break;
			case 7 : week = week_str[6];
					break;
			default: break;
		}
		
		Uart_Printf("\n%d年,%d月,%d日,星期%s,%d点,%d分,%d秒\n",2000+data[0], 
			data[1], data[3], week, data[4], data[5], data[6]);
			
		if (1 == alarm_flag){
			Uart_Printf("\nALARM:%d年,%d月,%d日,%d点,%d分,%d秒\n",2000+data[0], 
			data[1], data[3], data[4], data[5], data[6]);
			alarm_flag = 0;
		}
		
		if (1 == tick_flag){
			count++;
			Uart_Printf("\nTICK:%d\n", count);
			tick_flag = 0;
		}
		
		delay(50);
	}
}

RTC.c部分

#include "2440addr.h"

/*定义用户中断标志*/
char tick_flag = 0, alarm_flag = 0;
void __irq RTC_alarm_interrupt(void);
void __irq RTC_tick_interrupt(void);

/*RTC初始化*/
void RTC_Init(void)
{
	rINTMSK &= ~(1<<30 | 1<<8);//RTC中断使能
	pISR_TICK = (unsigned)RTC_tick_interrupt;
	pISR_RTC = (unsigned)RTC_alarm_interrupt;
}

/*RTC设置*/
void RTC_Set(char year, char month, char week,
		char date, char hour, char min, char sec)
{
	rRTCCON = 1;
	
	rBCDYEAR = year;
	rBCDMON = ((month / 10)<<4) | (month % 10);
	rBCDDAY = week;
	rBCDDATE = ((date / 10)<<4) | (date % 10);
	rBCDHOUR = ((hour / 10)<<4) | (hour % 10);
	rBCDMIN = ((min / 10)<<4) | (min % 10);
	rBCDSEC = ((sec / 10)<<4) | (sec % 10);

	rRTCCON &= ~1;
}

/*读取RTC*/
void RTC_Read(char *year, char *month, char *week,
		char *date, char *hour, char *min, char *sec)
{
	char i;
	
	rRTCCON = 1;
	
	*year = rBCDYEAR;
	*month = (rBCDMON>>4) * 10 + (rBCDMON & 0x0f);
	*week = rBCDDAY;
	*date = (rBCDDATE>>4) * 10 + (rBCDDATE & 0x0f);
	*hour = (rBCDHOUR>>4) * 10 + (rBCDHOUR & 0x0f);
	*min = (rBCDMIN>>4) * 10 + (rBCDMIN & 0x0f);
	
	if ((*sec = rBCDSEC) == 0){
		*year = rBCDYEAR;
		*month = (rBCDMON>>4) * 10 + (rBCDMON & 0x0f);
		*week = rBCDDAY;
		*date = (rBCDDATE>>4) * 10 + (rBCDDATE & 0x0f);
		*hour = (rBCDHOUR>>4) * 10 + (rBCDHOUR & 0x0f);
		*min = (rBCDMIN>>4) * 10 + (rBCDMIN & 0x0f);
	}
	
	*sec = (rBCDSEC>>4) * 10 + (rBCDSEC & 0x0f);
	
	rRTCCON &= ~1;
}

/*RTC tick时钟设置*/
void RTC_Tick(void)
{
	rTICNT &= ~0xff;
	rTICNT |= (1<<7 | 63);
}

/*RTC 闹钟初始化*/
void RTC_Alarm(void)
{
	rRTCALM &= ~0xff;
	rRTCALM |= 0xff;
}

/*RTC 闹钟设置*/
void RTC_Alarm_Set(char year, char mon, char date,
		char hour, char min, char sec)
{
	rALMYEAR = year;
	rALMMON = ((mon / 10)<<4) | mon % 10;
	rALMDATE = ((date / 10)<<4) | date % 10;
	rALMHOUR = ((hour / 10)<<4) | hour % 10;
	rALMMIN = ((min / 10)<<4) | min % 10;
	rALMSEC = ((sec / 10)<<4) | sec % 10;
}

/*RTC 闹钟中断服务*/
void __irq RTC_alarm_interrupt(void)
{
	rSRCPND |= 1<<30;//清除中断
	rINTPND |= 1<<30;
	alarm_flag = 1;//设置用户中断标志
}

/*RTC tick中断服务*/
void __irq RTC_tick_interrupt(void)
{
	rSRCPND |= 1<<8;//清除中断
	rINTPND |= 1<<8;
	tick_flag = 1;//设置用户中断标志
}

运行结果如下:


源代码下载地址:http://download.csdn.net/detail/a16839678/6232721

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值