#include<reg52.h>
#define uint unsigned char
#define uchar unsigned int
Uint i,miao,fen,fen1,fen2,fen3,fen4,shi,shi1,shi2,shi3,shi4,flag1,flag2,flag3,flag4,flag5,aa,K1num,K2num,K3num,K4num,N;
uchar code table[]=" H.I.T CHINA ";
uchar code table2[]=" TIME ";
uchar code Alarm_0[]=" GBDS ";
uchar code Alarm_1[]=" SKDS ";
uchar code Alarm_2[]=" XKDS ";
uchar code Alarm_3[]=" DKDS ";
uchar code Alarm_00[]=" GB ";
uchar code Alarm_11[]=" SK ";
uchar code Alarm_22[]=" XK ";
uchar code Alarm_33[]=" DK ";
uchar code deng[]=" LIGHTING ";
sbit K1=P1^0; //四個按鍵
sbit K2=P1^1;
sbit K3=P1^2;
sbit K4=P1^3;
sbit rs=P2^0;
sbit rw=P2^1; //燈光控制端
sbit lcden=P2^2;
sbit LED2=P2^3; //廣播控制端
sbit led=P2^4; ///發光二極管控制端
sbit beep=P2^5; //蜂鳴器控制端
void delay(uint z) //延時函數
{uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--) ; }
void write_com(uchar com)//液晶寫命令函數
{rs=0;
rw=0;
lcden=0;
P3=com;
delay(5);
lcden=1;
delay(5);
lcden=0; }
void write_date(uchar date)//液晶寫數據函數
{ rs=1;
rw=0;
lcden=0;
P3=date;
delay(5);
lcden=1;
delay(5);
lcden=0; }
void write_sfm(uchar add,uchar date) //液晶寫時分秒函數
{uchar shi,ge;
shi=date/10;
ge=date%10;
write_com(0x80+0x40+add);
write_date(0x30+shi);
write_date(0x30+ge);}
void init() //初始化函數
{uint num; //寫液晶的循環控制變量
aa=0; //中斷次數標志
K1num=0; //K1按鍵被按下的標記變量
K2num=0; //K2按鍵被按下的標記變量
K3num=0; //K3按鍵被按下的標記變量
K4num=0; //K4按鍵被按下的標記變量
flag1=1; //控制lcd屏刷新的變量
flag2=1;//控制鬧鐘響鬧開啟關閉的標記
flag3=1;//控制鬧鐘響起時,按下K4停止鬧鐘響鬧的標記
flag4=1;//進入鬧鐘設置時的標記變量
flag5=1;//進入時間設置時的標記變量
led=1; //發光二極管初始化
LED2=0; //廣播初始化
rw=0;
N=100; //系統啟動時,鬧鐘時間到發出的聲音為連續三次發出“嘩”的一聲
miao=0; //系統初始化時間
fen=0;
shi=7;
fen1=6; //初始化鬧鐘的時間
shi1=7;
fen2=8; //初始化鬧鐘的時間
shi2=7;
fen3=10; //初始化鬧鐘的時間
shi3=7;
fen4=12; //初始化鬧鐘的時間
shi4=7;
beep=0; //蜂鳴器初始化
lcden=0; //液晶使能端初始化
write_com(0x38); //1602液晶初始化,設置16*2顯示。5*7點陣,8位數據接口
write_com(0x0c);//設置開顯示,不顯示光
write_com(0x06); //寫一個字符后地址指針自動加1
write_com(0x01);//顯示清0數據指針清0
write_com(0x80); //將數據指針定位到第一行,第一個字處
for(num=0;num<15;num++) //顯示鬧鐘標示: H.I.T CHINA
{ write_date(table[num]);delay(10); }
write_com(0x80+0x40+11);//寫出時間顯示部分的兩個冒號
write_date(':');
write_com(0x80+0x40+14);
write_date(' ');
write_com(0x80+0x40+15);
write_date(' ');
write_sfm(12,fen); //送去液晶顯示秒分時
write_sfm(9,shi);
TMOD=0x01; //設置定時器0為工作方式1
TH0=(65536-50000)/256;//定時器裝初值
TL0=(65536-50000)%256;
EA=1; //開總中斷
ET0=1; //開定時器0中斷
TR0=1; }
void xianshi() //系統時間顯示
{write_com(0x80+0x40);
for(i=0;i<9;i++)
write_date(table2[i]);
write_com(0x80+0x40+11);//寫出時間顯示部分的兩個冒號
write_date(':');
write_com(0x80+0x40+14);
write_date(' ');
write_com(0x80+0x40+15);
write_date(' ');
write_sfm(12,fen); //送去液晶顯示秒分時
write_sfm(9,shi); }
void time() //更改系統時間
{if( (K1num==0)&&(flag3==1) )
{write_com(0x80+0x40);
for(i=0;i<9;i++)
write_date(table2[i]); }
if(K1==0)//判斷K1按下,則開始修改時間
{delay(5);
flag5=1;
if(K1==0&&K1num==0)
{K1num=1;
while(!K1) //判斷是否松開按鍵,后同
if(K1num==1)
{ TR0=0; //關閉計數器0
write_com(0x0f); //光標開始閃爍
write_com(0x80+0x40+13);} } }
if(K1==0&&K1num==1) //判斷K1按下,修改系統時間的小時
{ delay(5);
if(K1==0)
{write_com(0x80+0x40+10); //光標定位到小時位置
K1num=1; //置K1num=1
while(!K1);
shi++; //則調整時加1
if(shi==24) shi=0; //若滿24后將清零
write_sfm(9,shi); //每調節一次送液晶顯示
write_com(0x80+0x40+10);} }
if(K2==0&&K1num==1) //判K2按下,修改系統時間的分鐘
{delay(5);
if(K2==0)
{write_com(0x80+0x40+13); //光標定位到分鐘位置
K1num=1;
while(!K2);
fen++; //則調整分加1
if(fen==60) fen=0;//若滿60后將清零
write_sfm(12,fen); //每調節一次送液晶顯示
write_com(0x80+0x40+13); } }
if(K1num==1) //當設置時間或鬧鐘時,K3被按下設置完成。
{ if(K3==0) //判斷K3按下
{delay(5);
if(K3==0)
{ flag5=0;
K1num=0;
while(!K3);
write_com(0x0c); //取消光標閃
TR0=1; //啟動定時器使時鐘開始走
flag1=1;//flag=1.則修改系統時間時液晶顯示的系統時間值,flag=0,則為修改鬧鐘時間時,屏幕顯示的是修改鬧鐘時間的值
flag1=1;
write_com(0x80+0x40+11);
write_date(':');
write_com(0x80+0x40+14);
write_date(' ');
write_com(0x80+0x40+15);
write_date(' '); } } }}
void guangbo() //廣播定時
{if(K3num==0)
{write_com(0x80+0x40);
for(i=0;i<9;i++)
write_date(Alarm_00[i]); }
if(K3==0&&K3num==0) //判斷K3首次被按下,則設置鬧鐘
{delay(5); //延時消抖,后同
if(K3==0)
{ flag1=0;
write_com(0x80+0x40+13); //第一次按下光標定位到分鐘位置
while(!K3);
K3num=1;
write_com(0x80+0x40);
for(i=0;i<9;i++)
write_date(Alarm_0[i]);
write_sfm(12,fen1); //送去液晶顯示定時的分,時
write_sfm(9,shi1);
write_com(0x0f); //光標開始閃爍
write_com(0x80+0x40+13); //顯示位置回到調節處
} }
if(K2==0&&K3num==0) //K2被按下時顯示定時時間
{ delay(5);
if(K2==0)
{ write_sfm(12,fen1); //送去液晶顯示定時的分,時
write_sfm(9,shi1);
while(!K2);
write_sfm(12,fen); //K2松開顯示當前時間
write_sfm(9,shi);} }
if(K1==0&&K3num==1) //修改小時,判斷K1鍵按下,K3num=1,表示K3按鍵按下,則此時修改的是鬧鐘時間的小時
{delay(5);
if(K1==0)
{ write_com(0x80+0x40+10); //光標定位到小時位置
K3num=1;
while(!K1);
shi1++; //則調整定時的時加1
if(shi2==24) //若滿24后將清零
shi1=0;
write_sfm(9,shi1); //每調節一次送液晶顯示
write_com(0x80+0x40+10); //顯示位置重新回到調節處
} }
if(K2==0&&K3num==1)//按鍵2按下,修改鬧鐘時間的分鐘
{ delay(5);
if(K2==0)
{ write_com(0x80+0x40+13); //光標定位到分鐘位置
K3num=1;
while(!K2);
fen1++; //則調整分加1
if(fen1==60) //若滿60后將清零
fen1=0;
write_sfm(12,fen1);//每調節一次送液晶顯示
write_com(0x80+0x40+13); //顯示位置重新回到調節處
} }
if(K3num==1) //當設置鬧鐘時,K3被按下設置完成。
{ if(K3==0) //判斷K3按下
{ delay(5);
if(K3==0)
{ K1num=0;
K3num=0;
while(!K3);
write_com(0x0c); //光標停止閃爍
flag1=1; //flag=1.則修改系統時間時液晶顯示的系統時間值,flag=0,則為修改鬧鐘時間時,屏幕顯示的是修改鬧鐘時間的值
write_sfm(12,fen);//送去液晶顯示分,時
write_sfm(9,shi);
write_com(0x80+0x40+11);
write_date(':');
write_com(0x80+0x40+14);
write_date(' ');
write_com(0x80+0x40+15);
write_date(' ');}} } }
void shangke() //上課定時
{if( K3num==0)
{write_com(0x80+0x40);
for(i=0;i<9;i++)
write_date(Alarm_11[i]); }
if(K3==0&&K3num==0) //判斷K3首次被按下,則設置鬧鐘
{ delay(5); //延時消抖,后同
if(K3==0)
{ flag1=0;
write_com(0x80+0x40+13); //第一次按下光標定位到分鐘位置
while(!K3);
K3num=1;
write_com(0x80+0x40);
for(i=0;i<9;i++)
write_date(Alarm_1[i]);
write_sfm(12,fen2); //送去液晶顯示定
write_sfm(9,shi2);
write_com(0x0f); //光標開始閃爍
write_com(0x80+0x40+13); //顯示位置回到調節處
} }
if(K2==0&&K3num==0) //K2被按下時顯示定時時間
{ delay(5);
if(K2==0)
{ write_sfm(12,fen2); //送去液晶顯示定時的分,時
write_sfm(9,shi2);
while(!K2);
write_sfm(12,fen); //K2松開顯示當前時間
write_sfm(9,shi); } }
if(K1==0&&K3num==1) //修改小時,判斷K1鍵按下,K3num=1,表示K3按鍵按下,則此時修改的是鬧鐘時間的小時
{ delay(5);
if(K1==0)
{ write_com(0x80+0x40+10); //光標定位到小時位置
K3num=1;
while(!K1);
shi2++; //則調整定時的時加1
if(shi2==24) //若滿24后將清零
shi1=0;
write_sfm(9,shi2); //每調節一次送液晶顯示
write_com(0x80+0x40+10); //顯示位置重新回到調節處
} }
if(K2==0&&K3num==1) //按鍵2按下,修改鬧鐘時間的分鐘
{ delay(5);
if(K2==0)
{ write_com(0x80+0x40+13); //光標定位到分鐘位置
K3num=1;
while(!K2);
fen2++; //則調整分加1
if(fen1==60) //若滿60后將清零
fen1=0;
write_sfm(12,fen2); //每調節一次送液晶顯示一下
write_com(0x80+0x40+13); //顯示位置重新回到調節處
} }
if(K3num==1) //當設置時間或鬧鐘時,K3被按下設置完成。
{ if(K3==0) //判斷K3按下
{ delay(5);
if(K3==0)
{ K1num=0;
K3num=0;
while(!K3);
write_com(0x0c); //光標停止閃爍
flag1=1; //flag=1.則修改系統時間時液晶顯示的系統時間值,flag=0,則為修改鬧鐘時間時,屏幕顯示的是修改鬧鐘時間的值
write_sfm(12,fen);//送去液晶顯示分,時
write_sfm(9,shi);
write_com(0x80+0x40+11);
write_date(':');
write_com(0x80+0x40+14);
write_date(' ');
write_com(0x80+0x40+15);
write_date(' ');}}} }
void xiake() //下課定時
{ if( K3num==0)
{ write_com(0x80+0x40);
for(i=0;i<9;i++)
write_date(Alarm_22[i]); }
if(K3==0&&K3num==0) //判斷K3首次被按下,則設置鬧鐘
{delay(5); //延時消抖,后同
if(K3==0)
{ flag1=0;
write_com(0x80+0x40+13); //第一次按下光標定位到分鐘位置
while(!K3);
K3num=1;
write_com(0x80+0x40);
for(i=0;i<9;i++)
write_date(Alarm_2[i]);
write_sfm(12,fen3); //送去液晶顯示定時的分,時
write_sfm(9,shi3);
write_com(0x0f); //光標開始閃爍
write_com(0x80+0x40+13); //顯示位置回到調節處
}}
if(K2==0&&K3num==0) //K2被按下時顯示定時時間
{delay(5);
if(K2==0)
{ write_sfm(12,fen3); //送去液晶顯示定時的分,時
write_sfm(9,shi3);
while(!K2);
write_sfm(12,fen); //K2松開顯示當前時間
write_sfm(9,shi);} }
if(K1==0&&K3num==1) //修改小時,判斷K1鍵按下,K3num=1,表示K3按鍵按下,則此時修改的是鬧鐘時間的小時
{ delay(5);
if(K1==0)
{ write_com(0x80+0x40+10); //光標定位到小時位置
K3num=1;
while(!K1);
shi3++; //則調整定時的時加1
if(shi3==24) //若滿24后將清零
shi1=0;
write_sfm(9,shi3); //每調節一次送液晶顯示
write_com(0x80+0x40+10); //顯示位置重新回到調節處
} }
if(K2==0&&K3num==1) //卸螷2按下,修改鬧鐘時間的分鐘
{ delay(5);
if(K2==0)
{ write_com(0x80+0x40+13); //光標定位到分鐘位置
K3num=1;
while(!K2);
fen3++; //則調整分加1
if(fen1==60) //若滿60后將清零
fen1=0;
write_sfm(12,fen3);//每調節一次送液晶顯示
write_com(0x80+0x40+13); } }
if(K3num==1) //當設置時間或鬧鐘時,K3被按下設置完成。
{ if(K3==0) //判斷K3按下
{ delay(5);
if(K3==0)
{ K1num=0;
K3num=0;
while(!K3);
write_com(0x0c); //光標停止閃爍
flag1=1;
write_sfm(12,fen);//送去液晶顯示分,時
write_sfm(9,shi);
write_com(0x80+0x40+11);
write_date(':');
write_com(0x80+0x40+14);
write_date(' ');
write_com(0x80+0x40+15);
write_date(' ');}}} }
void dengkong() //燈光控制
{if(K3num==0)
{write_com(0x80+0x40);
for(i=0;i<9;i++)
write_date(Alarm_33[i]); }
if(K3==0&&K3num==0) //判斷K3首次被按下,則設置鬧鐘
{delay(5); //延時消抖,后同
if(K3==0)
{flag1=0;
write_com(0x80+0x40+13); //第一次按下光標定位到分鐘位置
while(!K3);
K3num=1;
write_com(0x80+0x40);
for(i=0;i<9;i++)
write_date(Alarm_3[i]);
write_sfm(12,fen4); //送去液晶顯示定時的分,時
write_sfm(9,shi4);
write_com(0x0f); //光標開始閃爍
write_com(0x80+0x40+13); //顯示位置回到調節處
} }
if(K2==0&&K3num==0) //K2被按下時顯示定時時間
{delay(5);
if(K2==0)
{write_sfm(12,fen4); //送去液晶顯示定時的分,時
write_sfm(9,shi4);
while(!K2);
write_sfm(12,fen); //K2松開顯示當前時間
write_sfm(9,shi);
} }
if(K1==0&&K3num==1) //修改小時,判斷K1鍵按下,K3num=1,表示K3按鍵按下,則此時修改的是鬧鐘時間的小時
{delay(5);
if(K1==0)
{write_com(0x80+0x40+10); //光標定位到小時位置
K3num=1;
while(!K1);
shi4++; //則調整定時的時加1
if(shi4==24) //若滿24后將清零
shi1=0;
write_sfm(9,shi4); //每調節一次送液晶顯示一下
write_com(0x80+0x40+10); //顯示位置重新回到調節處
} }
if(K2==0&&K3num==1) //按鍵2按下,修改鬧鐘時間的分鐘
{ delay(5);
if(K2==0)
{ write_com(0x80+0x40+13); //光標定位到分鐘位置
K3num=1;
while(!K2);
fen4++; //則調整分加1
if(fen1==60) //若滿60后將清零
fen1=0;
write_sfm(12,fen4); //每調節一次送液
write_com(0x80+0x40+13); //顯示位置重新回到調節處
} }
if(K3num==1) //當設置時間或鬧鐘時,K3被按下設置完成。
{ if(K3==0) //判斷K3按下
{ delay(5);
if(K3==0)
{K1num=0;
K3num=0;
while(!K3);
write_com(0x0c); //光標停止閃爍
flag1=1;//flag=1.
write_sfm(12,fen);//送去液晶顯示分,時
write_sfm(9,shi);
write_com(0x80+0x40+11);
write_date(':');
write_com(0x80+0x40+14);
write_date(' ');
write_com(0x80+0x40+15);
write_date(' ');}} }}
void clock()//任意鬧鐘時間到鬧鐘響
{if((((fen==fen1)&&(shi==shi1))||((fen==fen2)&&(shi==shi2))||((fen==fen3)&&(shi==shi3))||((fen==fen4)&&(shi==shi4)))&&(flag2==1)) //鬧鐘的響鬧控制
{beep=1; //此時鬧鐘響起,連續三次發出嘩的一聲
flag5=0;
flag3=0; //置flag3=0,表示此時鬧鐘響起,按下K4鍵執行停止鬧鐘響鬧語句
delay(100); //這些語句是為了使鬧鐘響起時,發出連續三次嘩的聲音
beep=0;
delay(100);
beep=1;
delay(100);
beep=0;
delay(100);
beep=1;
delay(100);
beep=0;
delay(300); }
else
{beep=0;}
if(((fen!=fen1)&&(fen!=fen2)&&(fen!=fen3)&&(fen!=fen4))&&(flag4==0)&&(flag5==0) )//顯示時間
{ xianshi(); }
if((fen==fen1)&&(shi==shi1)&&(flag2==1))
{LED2=1;
write_com(0x80+0x40);
for(i=0;i<9;i++)
write_date(Alarm_00[i]);
write_sfm(12,fen1); //送去液晶顯示定時的分,時
write_sfm(9,shi1); }
else {LED2=0;}
if((((fen==fen1)&&(shi==shi1)&&(flag2==0))||((fen-1==fen1)&&(shi==shi1)))&&(flag4==0) )
{ xianshi();}
if((fen==fen2)&&(shi==shi2)&&(flag2==1))
{write_com(0x80+0x40);
for(i=0;i<9;i++)
write_date(Alarm_11[i]);
write_sfm(12,fen2); //送去液晶顯示定時的分,時
write_sfm(9,shi2); }
if((((fen==fen2)&&(shi==shi2)&&(flag2==0))||((fen-1==fen2)&&(shi==shi2)))&&(flag4==0) )
{ xianshi(); }
if((fen==fen3)&&(shi==shi3)&&(flag2==1))
{write_com(0x80+0x40);
for(i=0;i<9;i++)
write_date(Alarm_22[i]);
write_sfm(12,fen3); //送去液晶顯示定時的分,時
write_sfm(9,shi3); }
if((((fen==fen3)&&(shi==shi3)&&(flag2==0))||((fen-1==fen3)&&(shi==shi3)))&&(flag4==0))
{xianshi(); }
if((fen==fen4)&&(shi==shi4)&&(flag2==1))
{write_com(0x80+0x40);
for(i=0;i<15;i++)
write_date(deng[i]); }
if((((fen==fen4)&&(shi==shi4)&&(flag2==0))||((fen-1==fen4)&&(shi==shi4)))&&(flag4==0) )
{ xianshi();} }
void main() //主函數
{init();//初始化子程序
while(1)
{ if((K4==0)&&(flag3==1))
{ delay(200);
K4num++;
delay(100);
if(K4num==5)
K4num=0;}
if(K4==0&&flag3==0) //當鬧鐘響起時,按下K4停止響鬧,當鬧鐘響起時候flag3置為0
{delay(5);
if(K4==0)
{flag2=0;
flag3=1;}
delay(300);}
if(K4num==0)
{time();
flag4=0; }
if(K4num==1)
{guangbo();
flag4=1;}
if(K4num==2)
{ shangke();
flag4=1; }
if(K4num==3)
{ xiake();
flag4=1; }
if(K4num==4)
{ dengkong();
flag4=1; }
clock();}}
void time0() interrupt 1 //定時器0中斷服務程序
{TH0=(65536-50000)/256; //定時器重新裝入數值
TL0=(65536-50000)%256;
aa++; //中斷次數累加
if(aa==20) //20次50毫秒為1秒
{ aa=0;
miao++;
led=~led;
if(miao==60)
{miao=0;
fen++;
flag2=1;//鬧鐘響起時按下K4鍵鬧鐘關閉,此處應重置該變量,使下一次鬧鐘時間來到時,鬧鐘仍然可以響起
if(fen==60)
{ fen=0;
shi++;
if(shi==24)
{ shi=0; }
if(flag1==1)
{write_sfm(9,shi);
write_com(0x80+0x40+11);
write_date(':');
write_com(0x80+0x40+14);
write_date(' ');
write_com(0x80+0x40+15);
write_date(' ');}}
if(flag1==1)
{write_sfm(12,fen);
write_com(0x80+0x40+11);
write_date(':');
write_com(0x80+0x40+14);
write_date(' ');
write_com(0x80+0x40+15);
write_date(' ');} //分鐘發生變化則立即吸入屏幕顯示
} } }
原代碼附上 |