#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
uchar code table[]=" 2013-09-23 MON"; //設定開始顯示的時間
uchar code table1[]=" 00:00:01";
uchar code table2[7][3]= {{"MON"},{"TUE"},{"WED"},{"THU"},{"FRI"},{"SAT"},{"SUN"}}; //定義二維字符數組
sbit wr=P1^1; // 1602液晶的讀/寫端
sbit lcden=P1^2; // 1602液晶使能端
sbit lcdrs=P1^0; // 1602液晶命令/數據端
sbit key1=P3^2; // 聲明s1按鍵時間調整
sbit key2=P3^3; // 聲明s2按鍵+1
sbit key3=P3^4; // 聲明s3按鍵-1
sbit key4=P3^5; // 聲明s4按鍵鬧鐘調整
sbit beep=P1^4; // 聲明蜂鳴器
uchar num1,shi=00,fen=00,miao=01,yue=9,ri=23,shi1,fen1,miao1,keynum1,week; //定義時分秒變量
uint nian=2013; //定義年變量
void delayms(uint x)
{
uint i,j;
for(i=x;i>0;i--) //定義帶參數延時函數
for(j=110;j>0;j--);
}
void write_com(uchar com) //1602液晶寫指令函數
{ wr=0;
lcdrs=0;
P0=com;
delayms(1);
lcden=1;
delayms(1);
lcden=0;
}
void write_date(uchar date) //1602液晶寫數據函數
{ wr=0;
lcdrs=1;
P0=date;
delayms(1);
lcden=1;
delayms(1);
lcden=0;
}
void write_addate1(uchar add,uint date) //定義顯示年的函數
{ uint qian;
uchar bai,shi,ge;
qian=date/1000;
bai=date%1000/100;
shi=date%1000%100/10;
ge=date%10;
write_com(add+0x80);
write_date(0x30+qian);
write_date(0x30+bai);
write_date(0x30+shi);
write_date(0x30+ge);
}
void write_addate2(uchar add,uchar date) //定義顯示月、日、時、分、秒函數
{
uchar shi,ge;
shi=date/10;
ge=date%10;
write_com(add+0x80);
write_date(0x30+shi);
write_date(0x30+ge);
}
void write_rq(uchar i) //定義顯示星期的函數
{ uchar x;
for(x=0;x<3;x++)
{ write_date(table2[i][x]);
delayms(1);
}
}
void init () //定義初始化函數
{
TMOD=0x01; // 定時器0工作方式為11.0592M晶振 16位
TH0=(65536-45566)/256; // 裝初值
TL0=(65536-45566)%256;
EA=1; // 開總中斷
ET0=1; // 開定時器0中斷
write_com(0x38); // 設置16*2顯示,5*7點陣,8位數據口
write_com(0x06); // 寫一個字符后地址指針加1
write_com(0x0c); // 設置開顯示,不顯示光標
write_com(0x01); // 顯示清0,數據清0
write_com(0x80); // 使指針指向第1行第1列
}
void keyscan() // 定義按鍵函數
{
uchar keynum;
if(key1==0) //s1按鍵被按下
{ delayms(3); //去抖延時
if(key1==0) //確認s4按鍵被按下,進入調時間模式
{
keynum++;
while(!key1); //松手檢測
}
if(keynum==1) //s1按下一次
{ TR0=0; //關閉定時器0
write_com(0x81); //指針指向第1行2列
write_com(0x0f); //開啟光標顯示,光標閃爍
}
if(keynum==2)
{
write_com(0x86); //光標跳到月份
}
if(keynum==3)
{
write_com(0x89); //光標跳到日
}
if(keynum==4)
{
write_com(0x8c); //光標跳到星期
}
if(keynum==5)
{
write_com(0xc4); //光標跳到時
}
if(keynum==6)
{
write_com(0xc7); //光標跳到分
}
if(keynum==7)
{
write_com(0xca); //光標跳到秒
}
if(keynum==8)
{ keynum=0; //退出調時間模式
TR0=1; //開啟定時器0
write_com(0x0c); //關閉光標顯示
}
}
if(keynum) //當進入調時間模式時
{
if(key2==0) //s2按鍵按下
{
delayms(3); //去抖延時
if(key2==0)
{
if(keynum==1)
{
nian++; //s2每按下一次年份加1
if(nian==10000) // 加滿清0
nian=0;
write_addate1(1,nian); // 顯示年份
write_com(0x81); //寫完數據指針指向年份原來位置
}
if(keynum==2)
{
yue++; //s2每按下一次月份加1
if(yue==13)
yue=0; //加滿清0
write_addate2(6,yue); //顯示月份
write_com(0x86); //寫完數據指針指向月份原來位置
}
if(keynum==3)
{ ri++;
if(yue==1||yue==3||yue==5||yue==7||yue==8||yue==10||yue==12) //1,3,5,7,8,10,12月有31天
if(ri==32) //加滿還原
ri=1;
if(yue==4||yue==6||yue==9||yue==11) //4,6,9,11月有30天
if(ri==31)
ri=1;
if(yue==2&&((nian%4==0&&nian%100!=0)||nian%400==0)) //閏年2月有30天
if(ri==30)
ri=1;
if(yue==2&&(nian%4!=0)||(nian%100==0&&nian%400!=0)) //非閏年2月有31天
if(ri==29)
ri=1;
write_addate2(9,ri); //顯示日
write_com(0x89); //寫完數據指針指向日原來位置
}
if(keynum==4)
{
week++; //s2每按下一次星期加1
if(week==7) //加滿還原
week=0;
write_rq(week); //顯示星期
write_com(0x8c); //寫完數據指針指向星期原來位置
}
if(keynum==5)
{
shi++; //s2每按下一次時加1
if(shi==24)
shi=0; //加滿還原
write_addate2(0x44,shi); //顯示時
write_com(0xc4); //寫完數據指針指向時原來位置
}
if(keynum==6)
{
fen++; //s2每按下一次分加1
if(fen==60)
fen=0; //加滿還原
write_addate2(0x47,fen); //顯示分
write_com(0xc7); //寫完數據指針指向分原來位置
}
if(keynum==7)
{
miao++; //s2每按下一次秒加1
if(miao==60)
miao=0; //加滿還原
write_addate2(0x4a,miao); //顯示秒
write_com(0xca); //寫完數據指針指向秒原來位置
}
while(!key2); //松手檢測
}
}
if(key3==0)
{
delayms(3);
if(key3==0)
{ //s3按下時減1
if(keynum==1)
{
nian--;
if(nian==-1)
nian=9999;
write_addate1(1,nian);
write_com(0x81);
}
if(keynum==2)
{ yue--;
if(yue==-1)
yue=12;
write_addate2(6,yue);
write_com(0x86);
}
if(keynum==3)
{
ri--;
if(ri==0)
{ if(yue==1||yue==3||yue==5||yue==7||yue==8||yue==10||yue==12)
ri=31;
if(yue==4||yue==6||yue==9||yue==11)
ri=30;
if(yue==2&&((nian%4==0&&nian%100!=0)||nian%400==0))
ri=29;
if(yue==2&&(nian%4!=0)||(nian%100==0&&nian%400!=0))
ri=28;
}
write_addate2(9,ri);
write_com(0x89);
}
if(keynum==4)
{
week--;
if(week==-1)
week=6;
write_rq(week);
write_com(0x8c);
}
if(keynum==5)
{
shi--;
if(shi==-1)
shi=23;
write_addate2(0x44,shi);
write_com(0xc4);
}
if(keynum==6)
{
fen--;
if(fen==-1)
fen=59;
write_addate2(0x47,fen);
write_com(0xc7);
}
if(keynum==7)
{
miao--;
if(miao==-1)
miao=59;
write_addate2(0x4a,miao);
write_com(0xca);
}
while(!key3); //松手檢測
}
}
}
if(key4==0) //s4被按下進入調鬧鐘模式
{ delayms(3);
if(key4==0)
{
keynum1++;
while(!key4);
}
if(keynum1==1)
{ write_com(0x01); //清屏,指針清0
write_com(0xc6); //在時分之間顯示“:”
write_date(':');
write_com(0xc9); //在分秒之間顯示“:”
write_date(':');
write_com(0x0f); //開啟光標
write_com(0xc4); //光標指向時
}
if(keynum1==2)
{
write_com(0xc7); //光標指向分
}
if(keynum1==3)
{
write_com(0xca); //光標指向秒
}
if(keynum1==4)
{ keynum1=0;
write_com(0x0c); //關閉光標
}
}
if(keynum1)
{
if(key2==0) //s2按下加1
{
delayms(3);
if(key2==0)
{
if(keynum1==1)
{
shi1++;
if(shi1==24)
shi1=0;
write_addate2(0x44,shi1);
write_com(0xc4);
}
if(keynum1==2)
{
fen1++;
if(fen1==60)
fen1=0;
write_addate2(0x47,fen1);
write_com(0xc7);
}
if(keynum1==3)
{
miao1++;
if(miao1==60)
miao1=0;
write_addate2(0x4a,miao1);
write_com(0xca);
}
while(!key2);
}
}
if(key3==0) //s3每按一次減1
{
delayms(3);
if(key3==0)
{
if(keynum1==1)
{
shi1--;
if(shi1==-1)
shi1=23;
write_addate2(0x44,shi1);
write_com(0xc4);
}
if(keynum1==2)
{
fen1--;
if(fen1==-1)
fen1=59;
write_addate2(0x47,fen1);
write_com(0xc7);
}
if(keynum1==3)
{
miao1--;
if(miao1==-1)
miao1=59;
write_addate2(0x4a,miao1);
write_com(0xca);
}
while(!key3); //松手檢測
}
}
}
}
void main()
{ uchar num;
init();
for(num=0;num<15;num++)
{ write_date(table[num]);
delayms(5);
} //顯示初始時間
write_com(0xc0);
for(num=0;num<12;num++)
{ write_date(table1[num]);
delayms(5);
}
TR0=1; //開啟定時器0
while(1)
{
if(shi==shi1&&fen==fen1&&miao==miao1) //鬧鐘到了蜂鳴器響
beep=0;
if(shi==shi1&&fen==fen1&&miao==miao1+30) //鬧鐘到了蜂鳴器響
beep=1;
keyscan(); //掃描鍵盤
}
}
void time() interrupt 1 //中斷函數
{
TH0=(65536-45566)/256;
TL0=(65536-45566)%256; //進入中斷裝初值
num1++;
if(num1==20) //一秒到了
{ num1=0; //清0
miao++;
if(miao==60) //一分到了
{ miao=0; fen++; }
if(!keynum1) write_addate2(0x4a,miao); //當調鬧鐘模式按下時不顯示當前時間
if(fen==60)
{ fen=0;
shi++;
}
if(!keynum1) write_addate2(0x47,fen); //當調鬧鐘模式按下時不顯示當前時間
if(shi==24)
{
shi=0;
ri++;
week++;
}
if(!keynum1) write_addate2(0x44,shi); //當調鬧鐘模式按下時不顯示當前時間
if(yue==1||yue==3||yue==5||yue==7||yue==8||yue==10||yue==12)
if(ri==32)
{ ri=1; yue++; }
if(yue==4||yue==6||yue==9||yue==11)
if(ri==31)
{ ri=1; yue++; }
if(yue==2&&((nian%4==0&&nian%100!=0)||nian%400==0))
if(ri==30)
{ ri=1; yue++; }
if(yue==2&&(nian%4!=0)||(nian%100==0&&nian%400!=0))
if(ri==29)
{ ri=1; yue++; }
if(!keynum1) write_addate2(9,ri); //當調鬧鐘模式按下時不顯示當前時間
if(week==7)
week=0;
if(!keynum1) //當調鬧鐘模式按下時不顯示當前時間
{ write_com(0x8c);
write_rq(week);
}
if(yue==13)
{ yue=0;
nian++;
}
if(!keynum1) //當調鬧鐘模式按下時不顯示當前時間
{
write_addate2(6,yue);
write_com(0x88);
write_date('-');
}
if(nian==10000)
nian=0;
if(!keynum1)
{ write_addate1(1,nian); //當調鬧鐘模式按下時不顯示當前時間
write_com(0x85);
write_date('-');
}
}
}
|