⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rtc.c

📁 使用ARM7在Embest IDE对于S3CEV40进行时钟万年历设计.时钟可以有闹钟的功能.
💻 C
字号:
/*********************************************************************************************
* File:	rtc.c
* Author:	embest
* Desc:	rtc source code
* History:	
* 	Create: Rijing			Date: 2003.08.25
* 	Modify: (1)	Rijing		upDate:	2003.08.25
*			()				upDate: 
* Desc:	
*********************************************************************************************/
#include "44blib.h"
#include "44b.h"
#include "rtc.h"
#include "lcd.h"

#ifndef RTC_INT
#define RTC_INT
#endif

/*------------------------------------------------------------------------------------------*/
/*	 								global variables					 				    */
/*------------------------------------------------------------------------------------------*/
char *g_szDate[8] = {"","SUN","MON","TUE","WED","THU","FRI","SAT"};
volatile unsigned int f_unSecTick;
volatile int          f_nIsRtcInt;
char g_cRtcOK;
int  g_nYear,g_nMonth,g_nDay,g_nWeekday,g_nHour,g_nMin,g_nSec;

extern char sDATE[12];
extern char sTIME[8];


extern void isrRTC();						// implement in call_int.s
void rtc_display(void);

/*********************************************************************************************
* name:		rtc_init
* func:		rtc init
* para:		none
* ret:		none
* modify:
* comment:		
*********************************************************************************************/
void rtc_init(void)
{
	rRTCCON  = 0x01;						// R/W enable, 1/32768, Normal(merge), No reset
	// set the default data for RTC
	rBCDYEAR = TESTYEAR;
	rBCDMON  = TESTMONTH;
	rBCDDAY  = TESTDAY;						// SUN:1 MON:2 TUE:3 WED:4 THU:5 FRI:6 SAT:7
	rBCDDATE = TESTDATE;
	rBCDHOUR = TESTHOUR;
	rBCDMIN  = TESTMIN;
	rBCDSEC  = TESTSEC;
	rRTCCON  = 0x0;							// R/W disable, 1/32768, Normal(merge), No reset
    
	// display the default time
	//Uart_Printf("\n\r Set Default Time at 20%02x-%02x-%02x %s",TESTYEAR,TESTMONTH,TESTDAY,g_szDate[TESTDATE]);
	//Uart_Printf(" %02x:%02x:%02x\n\r",TESTHOUR,TESTMIN,TESTSEC);

}

/*********************************************************************************************
* name:		rtc_check
* func:		check rtc working or not
* para:		none
* ret:		cRtcAlarm = 0:
*			cRtcAlarm = 1: ok
* modify:
* comment:		
*********************************************************************************************/
char rtc_check(void)
{
	char cRtcAlarm = 0;
	char cYn = 0x59;
   
	// check RTC
	while((cYn == 0x0d)|(cYn == 0x59)|(cYn == 0x79)|(cRtcAlarm == 0))
	{
		Uart_Printf("\n\r RTC Check(Y/N)? ");
       
		// get data from keybroad
		cYn = Uart_Getch();
		Uart_SendByte(cYn);
		if((cYn == 0x0d)|(cYn == 0x59)|(cYn == 0x79))
		{
			cRtcAlarm = rtc_alarm_test();                             // test rtc alarm
			rtc_display();
		}
		else break;
		if (cRtcAlarm) break;
	}
	return cRtcAlarm;   
}

/*********************************************************************************************
* name:		rtc_read
* func:		read data from rtc
* para:		none
* ret:		none
* modify:
* comment:		
*********************************************************************************************/
void rtc_read(void)
{
	while(1)
	{
		// read the data from RTC registers
		if(rBCDYEAR == 0x99) 
			g_nYear = 0x1999;
		else 
	    	g_nYear = 0x2000 + rBCDYEAR;
	    	
		g_nMonth   = rBCDMON;
		g_nDay     = rBCDDAY;
		g_nWeekday = rBCDDATE;
		g_nHour    = rBCDHOUR;
		g_nMin     = rBCDMIN;
		g_nSec     = rBCDSEC;
		
		if(g_nSec != 0)
	    	break;
	}	 
}

/*********************************************************************************************
* name:		rtc_display
* func:		display data from rtc
* para:		none
* ret:		none
* modify:
* comment:		
*********************************************************************************************/
void rtc_display(void)
{
	rtc_read();
	Uart_Printf("\n\r Current Time is %02x-%02x-%02x %s",g_nYear,g_nMonth,g_nDay,g_szDate[g_nWeekday]);
	Uart_Printf(" %02x:%02x:%02x\r",g_nHour,g_nMin,g_nSec);
}

/*********************************************************************************************
* name:		rtc_set_date
* func:		get and check the DATE string from uart channel to set rtc
* para:		none
* ret:		cN09 = 0 : invalid string
*			cN09 = 1 : set date by input string and ok
* modify:
* comment:		
*********************************************************************************************/
char rtc_set_date(void)
{
	char	cYn,cN09=1;
	char	szStr[12];                                                 // xxxx-xx-xx x
	int		i,nTmp;

	rtc_read();
	Uart_Printf("\n\r Current date is (%04x,%02x,%02x, %s). input new date (yy-mm-dd w): "
				 ,g_nYear,g_nMonth,g_nDay,g_szDate[g_nWeekday]);
	Uart_GetString(szStr);					// get the data from uart
	
	// check the format of the data
	nTmp = 0;
	cN09 = 1;
	for(i = 0;((i <12)&(szStr[i] != '\0')); i++)
	{
		if((szStr[i] == '-')|(szStr[i] == ' '))
			nTmp += 1;
	}
	
	if(nTmp < 3)	// at least 2 '-' and 1 ' '
	{
		cN09 = 0; 
		Uart_Printf("\n\r Wrong value!!  To set again(Y/N)?\n\r");
	}
	else // check if number 0 - 9
	{
		nTmp = i - 1;						// adjust the account number
			
		// 1:MON 2:TUE 3:WED 4:THU 5:FRI 6:SAT 7:SUN
		if((szStr[nTmp] < '1' | szStr[nTmp] > '7'))			// check weekday
			cN09 = 0;
			
		for( i = nTmp; i >= 0; i--)
	    {
			if(!((szStr[i] == '-')|(szStr[i] == ' ')))
				if((szStr[i] < '0' | szStr[i] > '9'))
					cN09 = 0;
		}
	}
	
	// write the data into rtc register
	if(cN09)
	{
		rRTCCON  = 0x01;				// R/W enable, 1/32768, Normal(merge), No reset
		i = nTmp;
		nTmp = szStr[i]&0x0f;
		if(nTmp == 7)
			rBCDDATE = 1;				// s3c44b0x: SUN:1 MON:2 TUE:3 WED:4 THU:5 FRI:6 SAT:7
		else
			rBCDDATE = nTmp+1;			// -> weekday;
		
		nTmp = szStr[i-=2]&0x0f;
		if(szStr[--i] != '-')
			nTmp |= (szStr[i--]<<4)&0xff;
		if(nTmp > 0x31)
			cN09 = 0;
		rBCDDAY  = nTmp;				// -> day;
		
		nTmp = szStr[--i]&0x0f;
		if(szStr[--i] != '-')
			nTmp |= (szStr[i]<<4)&0xff;
		if(nTmp > 0x12)
			cN09 = 0;
		rBCDMON  = nTmp;				// -> month;

		nTmp = szStr[--i]&0x0f;
		if(i)
			nTmp |= (szStr[--i]<<4)&0xff;
		if(nTmp > 0x99)
			cN09 = 0;
		rBCDYEAR  = nTmp;				// -> year;
		rRTCCON  = 0x00;				// R/W disable
		
		Uart_Printf(" Current date is: 20%02x-%02x-%02x %s\n\r"
				 ,rBCDYEAR,rBCDMON,rBCDDAY,g_szDate[rBCDDATE]);

		if(!cN09)
			Uart_Printf("\n\r Wrong value!!  To set again(Y/N)?\n\r");
    }
    else  // if(!cN09)
		Uart_Printf("\n\r Invalid!  To set again(Y/N)?\n\r");
		
	return cN09;
}

/*********************************************************************************************
* name:		rtc_set_time
* func:		get and check the TIME string from uart channel to set rtc
* para:		none
* ret:		cN09 = 0 : invalid string
*			cN09 = 1 : set time by input string and ok
* modify:
* comment:		
*********************************************************************************************/
char rtc_set_time(void)
{
	char	cYn,cN09=1;
	char	szStr[8];                                                 // xx:xx:xx
	int		i,nTmp;

	rtc_read();
	Uart_Printf("\n\r Current time is (%02x:%02x:%02x). To set time(hh:mm:ss): ",g_nHour,g_nMin,g_nSec);
	Uart_GetString(szStr);				// get the data from uart

	// check the format of the data
	nTmp = 0;
	cN09 = 1;
	for(i = 0;((i < 8)&(szStr[i] != '\0')); i++)
	{
		if(szStr[i] == ':')
			nTmp += 1;
	}
	
	if(nTmp != 2)	// at least 3 ':'
		cN09 = 0;
	else
	{
		nTmp = i - 1;
		for( i = nTmp; i >= 0; i--)
	    {
			if(szStr[i] != ':')
				if((szStr[i] < '0' | szStr[i] > '9'))
					cN09 = 0;
		}
	}
	
	// write the data into rtc register
	if(cN09)
	{
		rRTCCON  = 0x01;				// R/W enable, 1/32768, Normal(merge), No reset

		i = nTmp;			
		nTmp = szStr[i]&0x0f;
		if(szStr[--i] != ':')
			nTmp |= (szStr[i--]<<4)&0xff;
		if(nTmp > 0x59)
			cN09 = 0;
		rBCDSEC  = nTmp;				// -> second;
		
		nTmp = szStr[--i]&0x0f;
		if(szStr[--i] != ':')
			nTmp |= (szStr[i--]<<4)&0xff;
		if(nTmp > 0x59)
			cN09 = 0;
		rBCDMIN  = nTmp;				// -> min;

		nTmp = szStr[--i]&0x0f;
		if(i)
			nTmp |= (szStr[--i]<<4)&0xff;
		if(nTmp > 0x24)
			cN09 = 0;
		rBCDHOUR  = nTmp;				// -> hour;

		rRTCCON  = 0x00;				// R/W disable		

		if(!cN09)
			Uart_Printf("\n\r Wrong value!!  To set again(Y/N)?\n\r");
	}
    else  // if(!cN09)
		Uart_Printf("\n\r Invalid!  To set again(Y/N)?\n\r");

	return cN09;
}

/*********************************************************************************************
* name:		rtc_test
* func:		rtc display
* para:		none
* ret:		none
* modify:
* comment:		
*********************************************************************************************/
void rtc_test(void)
{
	char	cYn;
	
	// user interface
	//Uart_Printf("\n\r RTC Test Example\n");  
	 
	// check if rtc work normally
	if(!rtc_check())
	{
		Uart_Printf("\n\r Please check RTC or maybe it's Wrong. \n");
		return;
		
	} 
	else
	 {
		Uart_Printf("\n\r RTC Working now. To set date(Y/N)? ");          
		cYn = 'y';							// yes
		while((cYn == 'y') | (cYn == 0x0d) | (cYn == 'Y') )
		{
			cYn = Uart_Getch();
			Uart_SendByte(cYn);
	
			if(!((cYn == 0x0d)|(cYn == 0x59)|(cYn == 0x79)))	// want to set date?
			{ 
				Uart_Printf("\n\r Use Current Settings...\n");
				break;
			}
			cYn = rtc_set_date();
			if(cYn)							// if all right, break
				break;
			cYn = 'y';						// to set again
		}
		
		cYn = 'y';							// yes
		while( (cYn == 0x0d) | (cYn == 0x59) | (cYn == 0x79) )
		{
			Uart_Printf("\n\r RTC Working now. To set time(Y/N)? ");          
			cYn = Uart_Getch();
			Uart_SendByte(cYn);
			if(!((cYn == 0x0d)|(cYn == 0x59)|(cYn == 0x79)))	// want to set time?
			{ 
				Uart_Printf("\n\r Use Current Settings...\n");
				break;
			}
			cYn = rtc_set_time();
			if(cYn)							// if all right, break
				break;
			cYn = 'y';						// to set again
		}
	}
	
	// display current time
	rtc_display();
	while(1)
	{
	    Uart_Printf(" %02x:%02x:%02x\r",rBCDHOUR,rBCDMIN,rBCDSEC);
	     
		if((rBCDHOUR == 0x24) & (rBCDMIN == 0x59) & (rBCDSEC == 0x59))
			rtc_display();
	}
}

/*********************************************************************************************
* name:		Rtc_Int
* func:		rtc interrupt handler
* para:		none
* ret:		none
* modify:
* comment:		
*********************************************************************************************/
void rtc_int(void)
{
	rI_ISPC = BIT_RTC;   
	// other inst. is needed only when cache=on & wrbuf=on & BSFRD=0
	Uart_Printf(" ... RTC Alarm Interrupt O.K. ...\n");
	f_nIsRtcInt = 1;
}

/*********************************************************************************************
* name:		Rtc_Tick
* func:		rtc tick
* para:		none
* ret:		none
* modify:
* comment:		
*********************************************************************************************/
void rtc_tick(void)
{
	rI_ISPC = BIT_TICK; 
	//Uart_Printf("\b\b\b\b\b\b\b%03d sec",f_unSecTick++);
	
	Lcd_DspAscII8x16(10,20,WHITE,sDATE);
	Lcd_DspAscII8x16(10,50,WHITE,sTIME);
	
	rtc_read();	
	sprintf(sDATE,"%02x-%02x-%02x %s",g_nYear,g_nMonth,g_nDay,g_szDate[g_nWeekday]);
	sprintf(sTIME,"%02x:%02x:%02x\r",g_nHour,g_nMin,g_nSec);
	Lcd_DspAscII8x16(10,20,BLUE,sDATE);
	Lcd_DspAscII8x16(10,50,BLUE,sTIME);
	
}

/*********************************************************************************************
* name:		rtc_alarm_test
* func:		test rtc alarm
* para:		none
* ret:		f_nIsRtcInt = 0 : rtc not work
*	        f_nIsRtcInt = 1 : rtc work fine
* modify:
* comment:		
*********************************************************************************************/  
int rtc_alarm_test(void)  
{
	int i;
	
	rtc_init();								// rtc init
	
	rRTCCON  = 0x01;						// R/W enable, 1/32768, Normal(merge), No reset
	// set the test data for RTC
	rALMYEAR = TESTYEAR2 ;
	rALMMON  = TESTMONTH2;
	rALMDAY  = TESTDAY2  ;
	rALMHOUR = TESTHOUR2 ;
	rALMMIN  = TESTMIN2  ;
	rALMSEC  = TESTSEC2+1; 
	rRTCCON  = 0x0;							// R/W disable(for power consumption), 1/32768, Normal(merge), No reset
    
	// display  the test time 
	Uart_Printf(" Set Alarm Time at 20%02x-%02x-%02x ",rALMYEAR,rALMMON,rALMDAY);
	Uart_Printf("%02x:%02x:%02x\n\r",rALMHOUR,rALMMIN,rALMSEC);
    
	f_nIsRtcInt = 0;
	
	// enable rtc interrupt
	rRTCALM  = 0x7f;    
	pISR_RTC = (unsigned int) isrRTC;
 	rINTMSK  = ~(BIT_GLOBAL|BIT_RTC);

	Delay(20000);							// wait
	rINTMSK |= BIT_RTC;  

	return f_nIsRtcInt;
        
}

/*********************************************************************************************
* name:		rtc_tick_test
* func:		test rtc tick
* para:		none
* ret:		none
* modify:
* comment:		
*********************************************************************************************/
void rtc_tick_test(void)
{   
	// enable rtc_tick interrupt
	pISR_TICK = (unsigned)rtc_tick;
	rINTMSK   = ~(BIT_GLOBAL|BIT_TICK); 
        
	f_unSecTick= 1;
	rTICINT    = 127+(1<<7);				// START
}

/*********************************************************************************************
* name:		rtc_set
* func:		set new date and time
* para:		none
* ret:		none
* modify:
* comment:		
*********************************************************************************************/
void rtc_set(void)
{   
	// check if rtc work normally
	if(!rtc_check())
		Uart_Printf("\n\r Please check RTC or maybe it's Wrong. \n");
	else
	{
		rtc_set_date();
		rtc_set_time();
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -