說明:此程序?yàn)椴┲鲄⒖计渌绦虬存I一為時間與日期切換鍵;按鍵二為時間或日期調(diào)整鍵,即當(dāng)顯示時間時,每按一次依次顯示小時、分鐘、秒;當(dāng)顯示日期時,每按一次依次顯示年、月、日;按鍵三和按鍵四依次為加鍵和減鍵,每按一次當(dāng)松開時相應(yīng)的變化一次。
#include <reg52.h>
#define uchar unsigned char
#define uint unsigned int
sbit T_CLK = P1^0; //DS1302管腳定義
sbit T_IO =
P1^1;
sbit T_RST = P1^2;
sbit KEY_1 = P1^3; //按鍵管腳定義
sbit KEY_2 = P1^4;
sbit KEY_3 = P1^5;
sbit KEY_4 = P1^6;
sbit ACC0 = ACC^0;
sbit ACC7 = ACC^7;
uchar
DUAN_CODE[]={0X3F,0X06,0X5B,0X4F,0X66,0X6D,0X7D,0X07,0X7F,0X6F,0X0}; //共陰極數(shù)碼管段碼表
uchar
BIT_CODE[]={0XFE,0XFD,0XFB,0XF7,0XEF,0XDF}; //數(shù)碼管位選
uchar
second,minute,hour,day,month,year,flag,keyvalue,value=0;
uchar Time[6]={0X0,0X0,0X0,0X0,0X0,0X0};
bit
setsecond,setminute,sethour,setday,setmonth,setyear,distime=1,disdate=0;
void Delay(unsigned int i)
{
unsigned int j;
for(j=0;j<i;j++);
}
unsigned char BCD2HEX(unsigned char
BCDChar)
{
unsigned
char temp;
temp=(BCDChar/16*10+BCDChar);
return
temp;
}
unsigned char HEX2BCD(unsigned char HEXChar)
{
unsigned
char temp;
temp=(HEXChar/10*16+HEXChar);
return
temp;
}
void WriteByteDS1302(unsigned char Data)
{
unsigned
char i;
ACC =
Data;
for(i=8;
i>0; i--)
{
T_IO =
ACC0;
T_CLK = 1;
T_CLK = 0;
ACC = ACC >> 1;
}
}
unsigned char ReadByteDS1302(void)
{
unsigned
char i;
for(i=8;
i>0; i--)
{
ACC = ACC
>>1;
ACC7 = T_IO;
T_CLK = 1;
T_CLK = 0;
}
return(ACC);
}
void WriteDS1302(unsigned char Addr,unsigned char Data)
{
T_RST =
0;
T_CLK =
0;
T_RST =
1;
WriteByteDS1302(Addr);
WriteByteDS1302(Data);
T_CLK =
1;
T_RST =
0;
}
unsigned char ReadDS1302(unsigned char Addr)
{
unsigned
char Data;
T_RST =
0;
T_CLK =
0;
T_RST =
1;
WriteByteDS1302(Addr);
Data =
ReadByteDS1302();
T_CLK =
1;
T_RST =
0;
return(Data);
}
void
DS1302_INI() //設(shè)置ds1302函數(shù),初始化時間和日期
{
WriteDS1302(0x8e,0x00); //關(guān)閉寫保護(hù),允許寫操作
WriteDS1302(0x80,0x51); //秒
WriteDS1302(0x82,0x59); //分
WriteDS1302(0x84,0x12); //時
WriteDS1302(0x86,0x20); //日
WriteDS1302(0x88,0x05); //月
WriteDS1302(0x8c,0x12); //年
WriteDS1302(0x90,0xa5); //充電
WriteDS1302(0xc0,0xf0); //判斷是否初始化一次標(biāo)識寫入
WriteDS1302(0x8e,0x80); //打開寫保護(hù),禁止寫操作
}
void ReadTime()
{
second =
BCD2HEX(Time[0]=ReadDS1302(0x81));
minute =
BCD2HEX(Time[1]=ReadDS1302(0x83));
hour = BCD2HEX(Time[2]=ReadDS1302(0x85));
day = BCD2HEX(Time[3]=ReadDS1302(0x87));
month = BCD2HEX(Time[4]=ReadDS1302(0x89));
year = BCD2HEX(Time[5]=ReadDS1302(0x8d));
}
void Set(unsigned char sel,unsigned char selby)
{
unsigned char address,item;
unsigned char max,min;
if(sel==0) {address=0x80;
max=59;min=0;} //秒
if(sel==1) {address=0x82;
max=59;min=0;} //分鐘
if(sel==2) {address=0x84;
max=23;min=0;} //小時
if(month==2)
{
if(flag==1)
{
if(sel==3) {address=0x86; max=29;min=1;}
}
else
{
if(sel==3) {address=0x86; max=28;min=1;}
}
}
else
{
if(month==1|month==3|month==5|month==7|month==8|month==10|month==12)
{
if(sel==3) {address=0x86; max=31;min=1;}
}
if(month==4|month==6|month==9|month==11)
{
if(sel==3) {address=0x86; max=30;min=1;}
}
}
if(sel==4) {address=0x88;
max=12;min=1;} //月
if(sel==5) {address=0x8c;
max=99;min=0;} //年
item=ReadDS1302(address+1)/16*10+ReadDS1302(address+1);
if
(selby==0) item++; else item--;
if(item>max)
item=min;
if(item<min) item=max;
WriteDS1302(0x8e,0x00);
WriteDS1302(address,item/10*16+item);
WriteDS1302(0x90,0xa5);
WriteDS1302(0x8e,0x80);
}
void Display()
{
uchar i=0;
for(i=0;i<6;i++)
{
P0=DUAN_CODE[Time[i]];
P2=BIT_CODE[i];
Delay(5);
P2=0xff;
}
}
void DisplayMode()
{
if(distime==1)
{
if(KEY_2==0)
{
Delay(10); //延時去抖
if(KEY_2==0)
{
while(KEY_2==0);
value++;
if(value>=4)value=0;
}
}
if(value==0)
{
sethour=0;
setminute=0;
setsecond=0;
setyear=0;
setmonth=0;
setday=0;
Time[0]=hour/10;
Time[1]=hour;
Time[2]=minute/10;
Time[3]=minute;
Time[4]=second/10;
Time[5]=second;
}
if(value==1)
{
sethour=1;
setminute=0;
setsecond=0;
setyear=0;
setmonth=0;
setday=0;
Time[0]=hour/10;
Time[1]=hour;
Time[2]=10;
Time[3]=10;
Time[4]=10;
Time[5]=10;
}
if(value==2)
{
sethour=0;
setminute=1;
setsecond=0;
setyear=0;
setmonth=0;
setday=0;
Time[0]=10;
Time[1]=10;
Time[2]=minute/10;
Time[3]=minute;
Time[4]=10;
Time[5]=10;
}
if(value==3)
{
sethour=0;
setminute=0;
setsecond=1;
setyear=0;
setmonth=0;
setday=0;
Time[0]=10;
Time[1]=10;
Time[2]=10;
Time[3]=10;
Time[4]=second/10;
Time[5]=second;
}
}
if(disdate==1)
{
if(KEY_2==0)
{
Delay(10); //延時去抖
if(KEY_2==0)
{
while(KEY_2==0);
value++;
if(value>=4)value=0;
}
}
if(value==0)
{
sethour=0;
setminute=0;
setsecond=0;
setyear=0;
setmonth=0;
setday=0;
Time[0]=year/10;
Time[1]=year;
Time[2]=month/10;
Time[3]=month;
Time[4]=day/10;
Time[5]=day;
}
if(value==1)
{
sethour=0;
setminute=0;
setsecond=0;
setyear=1;
setmonth=0;
setday=0;
Time[0]=year/10;
Time[1]=year;
Time[2]=10;
Time[3]=10;
Time[4]=10;
Time[5]=10;
}
if(value==2)
{
sethour=0;
setminute=0;
setsecond=0;
setyear=0;
setmonth=1;
setday=0;
Time[0]=10;
Time[1]=10;
Time[2]=month/10;
Time[3]=month;
Time[4]=10;
Time[5]=10;
}
if(value==3)
{
sethour=0;
setminute=0;
setsecond=0;
setyear=0;
setmonth=0;
setday=1;
Time[0]=10;
Time[1]=10;
Time[2]=10;
Time[3]=10;
Time[4]=day/10;
Time[5]=day;
}
}
}
void KeyCheck()
{
if(KEY_1==0)
{
Delay(5);
if(KEY_1==0)
{
keyvalue=1;
}
while(KEY_1==0)Display();
}
}
void KeyCheckADDorPLUS()
{
if(KEY_3==0)
{
Delay(5);
if(KEY_3==0)
{
while(KEY_3==0);
if(setsecond==1)Set(0,0);
else
if(setminute==1)Set(1,0);
else
if(sethour==1)Set(2,0);
else
if(setday==1)Set(3,0);
else
if(setmonth==1)Set(4,0);
else
if(setyear==1)Set(5,0);
}
}
if(KEY_4==0)
{
Delay(5);
if(KEY_4==0)
{
while(KEY_4==0);
if(setsecond==1)Set(0,1);
else
if(setminute==1)Set(1,1);
else
if(sethour==1)Set(2,1);
else
if(setday==1)Set(3,1);
else
if(setmonth==1)Set(4,1);
else
if(setyear==1)Set(5,1);
}
}
}
void ChangeDisplay()
{
if(keyvalue==1)
{
if(distime)
{
distime=0;
disdate=1;
}
else if(disdate)
{
distime=1;
disdate=0;
}
}
keyvalue=0;
}
void LeapYear(void)
{
if((year%4==0&&year0!=0)||(year0==0&&year@0==0))
{
flag=1;
}
else
{
flag=0;
}
if(flag==1&month==2&day==29&hour==0&minute==0&second==1)
{
WriteDS1302(0x8e,0x00);//允許寫操作
WriteDS1302(0x88,0x03);
WriteDS1302(0x86,0x01);
WriteDS1302(0x90,0xa5);//充電
WriteDS1302(0x8e,0x80);//禁止寫操作
}
if(flag==0&month==2&day==28&hour==0&minute==0&second==1)
{
WriteDS1302(0x8e,0x00);//允許寫操作
WriteDS1302(0x88,0x03);
WriteDS1302(0x86,0x01);
WriteDS1302(0x90,0xa5);//充電
WriteDS1302(0x8e,0x80);//禁止寫操作
}
}
void main()
{
DS1302_INI();
while(1)
{
KeyCheck();
ChangeDisplay();
ReadTime();
DisplayMode();
Display();
KeyCheckADDorPLUS();
DisplayMode();
LeapYear(); //閏年修正
}
}