实时时钟(RTC)的主要功能是在体系掉电的情况下,使用后备电源使时钟持续运转,然后不会丢掉时刻信息。
s3c2440内部集成了RTC模块,而且用起来也非常简略。其内部的寄存器BCDSEC,BCDMIN,BCDHOUR,BCDDAY,BCDDATE,BCDMON和BCDYEAR别离存储了当时的秒,分,小时,星期,日,月和年,一共时刻的数值都是BCD码。这些寄存器的内容可读可写,而且只要在寄存器RTCCON的第0位为1时才干进行读写操作。为了避免误操作,当不进行读写时,要把该位清零。当读取这些寄存器时,能够获悉当时的时刻;当写入这些寄存器时,能够改动当时的时刻。别的需求留意的是,由于有所谓的“一秒夺冠”,因而当读取到的秒为0时,需求从头再读取一遍这些寄存器的内容,才干确保时刻的正确。
下面的程序便是一个简略的RTC的比如。体系上电,或按键时,会在LCD上显现当时时刻的悉数信息。而且能够经过UART,在PC机上改动RTC,它们之间的协议为:当PC机发送0xAA时,一共这以后的7个数据别离为年、月、日、星期、小时、分和秒,在s3c2440接纳到这些数据后,发送0xAA以示结语;当PC机发送其他数据时,关于s3c2440来说没有任何含义,s3c2440仅仅把该数据再传回给PC机。为了简练和突出重点,鄙人面程序中,会省掉掉曾经文章中介绍过的内容,如不清楚,请翻看本博客中的其他相关内容。
unsigned char date_buffer[7];//别离一共年、月、日、星期、小时、分、秒
unsigned char flag;//用于一共更新LCD显现时刻的标志
//获取时刻
void get_date(void)
{
rRTCCON = 1;
date_buffer[0] = rBCDYEAR;//年
date_buffer[1] = rBCDMON;//月
date_buffer[2] = rBCDDATE;//日
date_buffer[3] = rBCDDAY;//星期
date_buffer[4] = rBCDHOUR;//小时
date_buffer[5] = rBCDMIN;//分
date_buffer[6] = rBCDSEC;//秒
//当秒为0时,从头读取
if(date_buffer[6]==0)
{
date_buffer[0] = rBCDYEAR;//年
date_buffer[1] = rBCDMON;//月
date_buffer[2] = rBCDDATE;//日
date_buffer[3] = rBCDDAY;//星期
date_buffer[4] = rBCDHOUR;//小时
date_buffer[5] = rBCDMIN;//分
date_buffer[6] = rBCDSEC;//秒
}
rRTCCON = 0;
}
//设置时刻
void set_date(void)
{
rRTCCON = 1 ;
rBCDYEAR = date_buffer[0] ;//年
rBCDMON= date_buffer[1] ;//月
rBCDDATE = date_buffer[2] ;//日
rBCDDAY= date_buffer[3] ;//星期
rBCDHOUR = date_buffer[4] ;//小时
rBCDMIN= date_buffer[5] ;//分
rBCDSEC= date_buffer[6] ;//秒
rRTCCON = 0 ;
}
//在LCD上显现时刻
void show_date(void)
{
unsigned char String[ ]=”当时时刻:”;
unsigned char String_Y[ ]=”年”;
unsigned char String_M[ ]=”月”;
unsigned char String_D[ ]=”日”;
unsigned char ToWeek[ ][7] = {“周日”,”星期一”,”星期二”,”星期三”,”周四”,”星期五”,”星期六”};
unsigned char qh,wh;
const unsigned char *mould;
int length = sizeof(String);
int k,xx;
get_date();//获取时刻
//在LCD上写“当时时刻:”这几个字
for(k=0,xx=0;k
qh=String[k]-0xa0;
wh=String[k+1]-0xa0;
mould = & __HZK[ (( qh – 1 )*94 + wh- 1 )*32 ];
Draw_Text16(30+xx,50,0x0f,mould);
xx+=16;
k++;
}
//鄙人一行显现详细的时刻,方式如:2010年04月03日星期六21:52:28
//年
//人为加上“20”
mould = & __ASCII[2*16];
Draw_ASCII(30,70,0×0,mould);
mould = & __ASCII[0*16];
Draw_ASCII(38,70,0×0,mould);
qh=(date_buffer[0]>>4)+48;
wh=(date_buffer[0]&0x0f)+48;
mould = & __ASCII[qh*16];
Draw_ASCII(46,70,0×0,mould);
mould = & __ASCII[wh*16];
Draw_ASCII(54,70,0×0,mould);
qh=String_Y[0]-0xa0;
wh=String_Y[1]-0xa0;
mould = & __HZK[ (( qh – 1 )*94 + wh- 1 )*32 ];
Draw_Text16(62,70,0x0f,mould);
//月
qh=(date_buffer[1]>>4)+48;
wh=(date_buffer[1]&0x0f)+48;
mould = & __ASCII[qh*16];
Draw_ASCII(78,70,0×0,mould);
mould = & __ASCII[wh*16];
Draw_ASCII(86,70,0×0,mould);
qh=String_M[0]-0xa0;
wh=String_M[1]-0xa0;
mould = & __HZK[ (( qh – 1 )*94 + wh- 1 )*32 ];
Draw_Text16(94,70,0x0f,mould);
//日
qh=(date_buffer[2]>>4)+48;
wh=(date_buffer[2]&0x0f)+48;
mould = & __ASCII[qh*16];
Draw_ASCII(110,70,0×0,mould);
mould = & __ASCII[wh*16];
Draw_ASCII(118,70,0×0,mould);
qh=String_D[0]-0xa0;
wh=String_D[1]-0xa0;
mould = & __HZK[ (( qh – 1 )*94 + wh- 1 )*32 ];
Draw_Text16(126,70,0x0f,mould);
//星期
for(k=0,xx=0;k<7-1;k++)
{
qh=ToWeek[date_buffer[3]][k]-0xa0;
wh=ToWeek[date_buffer[3]][k+1]-0xa0;
mould = & __HZK[ (( qh – 1 )*94 + wh- 1 )*32 ];
Draw_Text16(142+xx,70,0x0f,mould);
xx+=16;
k++;
}
//小时
qh=(date_buffer[4]>>4)+48;
wh=(date_buffer[4]&0x0f)+48;
mould = & __ASCII[qh*16];
Draw_ASCII(194,70,0×0,mould);
mould = & __ASCII[wh*16];
Draw_ASCII(202,70,0×0,mould);
mould = & __ASCII[ :*16 ];
Draw_ASCII(210,70,0x0f,mould);
//分
qh=(date_buffer[5]>>4)+48;
wh=(date_buffer[5]&0x0f)+48;
mould = & __ASCII[qh*16];
Draw_ASCII(218,70,0×0,mould);
mould = & __ASCII[wh*16];
Draw_ASCII(226,70,0×0,mould);
mould = & __ASCII[ :*16 ];
Draw_ASCII(234,70,0x0f,mould);
//秒
qh=(date_buffer[6]>>4)+48;
wh=(date_buffer[6]&0x0f)+48;
mould = & __ASCII[qh*16];
Draw_ASCII(242,70,0×0,mould);
mould = & __ASCII[wh*16];
Draw_ASCII(250,70,0×0,mould);
}
//按键中止,用于更新LCD上显现的时刻
void __irq Key4_ISR(void)
{
rSRCPND = rSRCPND | 0x1;
rINTPND = rINTPND | 0x1;
flag=1;//置标志
}
//UART中止,用于修正时刻
void __irq uartISP(void)
{
char ch;
static char temp;
static char count;
rSUBSRCPND |= 0x3;
rSRCPND |= 0x1<<28;
rINTPND |= 0x1<<28;
if(rUTRSTAT0 & 1)//接纳数据处理部分
{
ch = rURXH0;//接纳字节数据
if(ch==0xaa&&temp==0)//一共接纳到修正时刻的指令
{
temp=1;
count=0;
}
else if(temp==1)//接纳时刻数据
{
date_buffer[count]=ch;//顺次存入时刻数组内
count++;
if(count==7)//7个时刻数据悉数接纳结束
{
rUTXH0=0xaa;//发送0xAA
set_date();//设置时刻
count=0;
temp=0;
flag=1;//更新LCD上显现的时刻
}
}
else
rUTXH0=ch;//不是接纳时刻的指令
}
}
void Main(void)
{
//初始化寄存器,内容省掉
……
Brush_Background(0xffffff);//LCD布景为白色
show_date();//在LCD上显现时刻
flag=0;//清标志
while(1)
{
if(flag)//需求更新LCD上的显现时刻
{
Brush_Background(0xffffff);
show_date();
flag=0;//清标志
}
}
}