📄 rtc.c
字号:
/*********************************************************************************************
* File: rtc.c
* Author: embest
* Desc: rtc source code
* History:
*********************************************************************************************/
#include "44blib.h"
#include "44b.h"
#include "rtc.h"
#include <string.h>
/*------------------------------------------------------------------------------------------*/
/* global variables */
/*------------------------------------------------------------------------------------------*/
char *f_szdate[8] = {"","SUN","MON","TUE","WED","THU","FRI","SAT"};
volatile unsigned int f_unSecTick;
volatile int f_nIsRtcInt;
void uart_getstring(char *pString);
/*********************************************************************************************
* 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)
{
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) rtc_int;
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_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,f_szdate[TESTDATE]);
uart_printf(" %02x:%02x:%02x\n\r",TESTHOUR,TESTMIN,TESTSEC);
}
/*********************************************************************************************
* 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 20%02x-%02x-%02x %s",g_nYear,g_nMonth,g_nDay,f_szdate[g_nWeekday]);
uart_printf(" %02x:%02x:%02x\r",g_nHour,g_nMin,g_nSec);
}
/*********************************************************************************************
* 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_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:
*********************************************************************************************/
int rtc_set_date(char *pString)
{
char cN09=1;
char szStr[12]; // xxxx-xx-xx x
int i,nTmp;
memcpy((void *)szStr, pString, 12);
// 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(" InValid format!!\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"
,rBCDYEAR,rBCDMON,rBCDDAY,f_szdate[rBCDDATE]);
if(!cN09)
uart_printf(" Wrong value!\n");
}else uart_printf(" Wrong value!\n");
return (int)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:
*********************************************************************************************/
int rtc_set_time(char *pString)
{
char cN09=1;
char szStr[8]; // xx:xx:xx
int i,nTmp;
memcpy((void *)szStr, pString, 8);
// 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;
uart_printf(" InValid format!!\n\r");
}
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(" Wrong value!\n");
}else uart_printf(" Wrong value!\n");
return (int)cN09;
}
/*********************************************************************************************
* name: rtc_test
* func: rtc display
* para: none
* ret: none
* modify:
* comment:
*********************************************************************************************/
void rtc_test(void)
{
char cYn;
char szStr[12]; // xxxx-xx-xx x
// user interface
uart_printf("\n RTC Test Example\n");
// rtc_set_date("2005-05-10 2");
// rtc_set_time("21:56:58");
// check if rtc work normally
if(!rtc_check())
uart_printf(" Please check RTC or maybe it's Wrong. \n");
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 Use Current Settings...\n");
break;
}
rtc_read();
uart_printf(" Current date is (%04x,%02x,%02x, %s).\n input new date (yy-mm-dd w): "
,g_nYear,g_nMonth,g_nDay,f_szdate[g_nWeekday]);
uart_getstring(szStr); // get the data from uart
cYn = (char)rtc_set_date(szStr);
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 Use Current Settings...\n");
break;
}
rtc_read();
uart_printf(" Current time is (%02x:%02x:%02x).\n To set time(hh:mm:ss): ",g_nHour,g_nMin,g_nSec);
uart_getstring(szStr); // get the data from uart
cYn = (char)rtc_set_time(szStr);
if(cYn) // if all right, break
break;
cYn = 'y'; // to set again
}
}
// display current time
rtc_display();
uart_printf("\n");
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 __irq 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++);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -