|
#include<reg52.h> //包含單片機(jī)寄存器的頭文件 #include<intrins.h> //包含_nop_()函數(shù)定義的頭文件 #define uchar unsigned char #define uint unsigned int sbit RS=P2^0; //寄存器選擇位,將RS位定義為P2.0引腳 sbit RW=P2^1; //讀寫(xiě)選擇位,將RW位定義為P2.1引腳 sbit E=P2^2; //使能信號(hào)位,將E位定義為P2.2引腳 sbit BF=P0^7; //忙碌標(biāo)志位,將BF位定義為P0.7引腳 uchar code table[]="2016-11-29 WEEK2"; //初始化液晶顯示 16 uchar code table1[]="TIME: 12-34-56"; //14 uchar count,s1num; char second,minute,hour,day,month,year,week; sbit s1=P2^3; //功能鍵 sbit s2=P2^4; //加鍵 sbit s3=P2^5; //減鍵 sbit s4=P2^6; //保存并退出 /* 延時(shí)若干毫秒 */ void delay(uchar n) { uchar i,a,b; for(i=0;i<n;i++) for(b=199;b>0;b--) for(a=1;a>0;a--); } uchar BusyTest(void) { bit result; RS=0; //根據(jù)規(guī)定,RS為低電平,RW為高電平時(shí),可以讀狀態(tài) RW=1; E=1; //E=1,才允許讀寫(xiě) _nop_(); //空操作 _nop_(); _nop_(); _nop_(); //空操作四個(gè)機(jī)器周期,給硬件反應(yīng)時(shí)間 result=BF; //將忙碌標(biāo)志電平賦給 E=0; //將E恢復(fù)低電平 return result; } void WriteInstruction(uchar dictate) { while(BusyTest()==1); //如果忙就等待 RS=0; //根據(jù)規(guī)定,RS和R/W同時(shí)為低電平時(shí),可以寫(xiě)入指令 RW=0; E=0; //E置低電平(根據(jù)表8-6,寫(xiě)指令時(shí),E為高脈沖,//就是讓E從0到1發(fā)生正跳變,所以應(yīng)先置"0" _nop_(); _nop_(); //空操作兩個(gè)機(jī)器周期,給硬件反應(yīng)時(shí)間 P0=dictate; //將數(shù)據(jù)送入P0口,即寫(xiě)入指令或地址 _nop_(); _nop_(); _nop_(); _nop_(); //空操作四個(gè)機(jī)器周期,給硬件反應(yīng)時(shí)間 E=1; //E置高電平 _nop_(); _nop_(); _nop_(); _nop_(); //空操作四個(gè)機(jī)器周期,給硬件反應(yīng)時(shí)間 E=0; //當(dāng)E由高電平跳變成低電平時(shí),液晶模塊開(kāi)始執(zhí)行命令 } void WriteData(uchar y) { while(BusyTest()==1); RS=1; //RS為高電平,RW為低電平時(shí),可以寫(xiě)入數(shù)據(jù) RW=0; E=0; //E置低電平(根據(jù)表8-6,寫(xiě)指令時(shí),E為高脈沖,//就是讓E從0到1發(fā)生正跳變,所以應(yīng)先置"0" P0=y; //將數(shù)據(jù)送入P0口,即將數(shù)據(jù)寫(xiě)入液晶模塊 _nop_(); _nop_(); _nop_(); _nop_(); //空操作四個(gè)機(jī)器周期,給硬件反應(yīng)時(shí)間 E=1; //E置高電平 _nop_(); _nop_(); _nop_(); _nop_(); //空操作四個(gè)機(jī)器周期,給硬件反應(yīng)時(shí)間 E=0; //當(dāng)E由高電平跳變成低電平時(shí),液晶模塊開(kāi)始執(zhí)行命令 } void LcdInitiate(void) { uchar num; second=56; minute=34; hour=12; week=6; day=7; month=12; year=13; count=0; s1num=0; E=0; delay(15); //延時(shí)15ms,首次寫(xiě)指令時(shí)應(yīng)給LCD一段較長(zhǎng)的反應(yīng)時(shí)間 WriteInstruction(0x38); //顯示模式設(shè)置:16×2顯示,//5×7點(diǎn)陣,8位數(shù)據(jù)接口 delay(5);//延時(shí)5ms,給硬件一點(diǎn)反應(yīng)時(shí)間 WriteInstruction(0x38); delay(5); WriteInstruction(0x38);//連續(xù)三次,確保初始化成功 delay(5); WriteInstruction(0x0c);//顯示模式設(shè)置:顯示開(kāi),無(wú)光標(biāo),//光標(biāo)不閃爍 delay(5); WriteInstruction(0x06);//顯示模式設(shè)置:光標(biāo)右移,字符不移 delay(5); WriteInstruction(0x01);//清屏幕指令,將以前的顯示內(nèi)容清除 delay(5); WriteInstruction(0x80); for(num=0;num<16;num++)//讓液晶顯示日期 { WriteData(table[num]); delay(5); } WriteInstruction(0x80+0x40); for(num=0;num<14;num++)//讓液晶顯示時(shí)間 { WriteData(table1[num]); delay(5); } TMOD=0x01;//定時(shí)器中斷初始化 TH0=(65536-50000)/256; TL0=(65536-50000)%256; EA=1; ET0=1; TR0=1; } void write_nyr(uchar add,uchar date) { uchar i,j; i=date/10; j=date%10; WriteInstruction(0x80+add); WriteData(0x30+i); WriteData(0x30+j); } void write_sfm(uchar add,uchar date) { uchar i,j; i=date/10; j=date%10; WriteInstruction(0x80+0x40+add); WriteData(0x30+i); WriteData(0x30+j); } void write_week(uchar add,uchar date) { WriteInstruction(0x80+add); WriteData(0x30+date); } bit leap_year() { int leap; if((year%4==0&&year%100!=0)||year%400==0) leap=1;//是閏年 else leap=0;//非閏年 return leap; } void keyscan() { if(s1==0) //第一個(gè)鍵是否按下 { delay(5); if(s1==0) { while(!s1); s1num++; if(s1num>7) s1num=1; if(s1num==1)//第一個(gè)鍵被按一次 { TR0=0; WriteInstruction(0x80+0x40+13); WriteInstruction(0x0f); } if(s1num==2) { WriteInstruction(0x80+0x40+10); } if(s1num==3) { WriteInstruction(0x80+0x40+7); } if(s1num==4) { WriteInstruction(0x80+9); } if(s1num==5) { WriteInstruction(0x80+6); } if(s1num==6) { WriteInstruction(0x80+3); } if(s1num==7) { WriteInstruction(0x80+15); } } } if(s1num!=0) //如果功能鍵被按下 { if(s2==0) //第二個(gè)按下 { delay(5); if(s2==0) { while(!s2); if(s1num==1) //第一個(gè)鍵被按一次,秒鐘加一 { second++; if(second==60) second=0; write_sfm(12,second); WriteInstruction(0x80+0x40+13); } if(s1num==2) //第一個(gè)鍵被按二次,分鐘加一 { minute++; if(minute==60) minute=0; write_sfm(9,minute); WriteInstruction(0x80+0x40+10); } if(s1num==3) //第一個(gè)鍵被按三次,時(shí)鐘加一 { hour++; if(hour==24) hour=0; write_sfm(6,hour); WriteInstruction(0x80+0x40+7); } if(s1num==4) //第一個(gè)鍵被按四次,日期加一 { day++; if(day==32) day=1; write_nyr(8,day); WriteInstruction(0x80+9); } if(s1num==5) //第一個(gè)鍵被按五次,月加一 { month++; if(month==13) month=1; write_nyr(5,month); WriteInstruction(0x80+6); } if(s1num==6) //年加一 { year++; if(year==99) year=0; write_nyr(2,year); WriteInstruction(0x80+3); } if(s1num==7) //星期加一 { week++; if(week==8) week=1; write_week(15,week); WriteInstruction(0x80+15); } } } if(s3==0) //第三個(gè)鍵被按下 { delay(5); if(s3==0) { while(!s3); if(s1num==1)//秒減一 { second--; if(second==-1) second=59; write_sfm(12,second); WriteInstruction(0x80+0x40+13); } if(s1num==2) //分減一 { minute--; if(minute==-1) minute=59; write_sfm(9,minute); WriteInstruction(0x80+0x40+10); } if(s1num==3) //時(shí)減一 { hour--; if(hour==-1) hour=23; write_sfm(6,hour); WriteInstruction(0x80+0x40+7); } if(s1num==4) //日減一 { day--; if(day==0) day=31; write_nyr(8,day); WriteInstruction(0x80+9); } if(s1num==5) //月減一 { month--; if(month==0) month=12; write_nyr(5,month); WriteInstruction(0x80+6); } if(s1num==6) //年減一 { year--; if(year==-1) year=99; write_nyr(2,year); WriteInstruction(0x80+3); } if(s1num==7) //日期減一 { week--; if(week==0) week=7; write_week(15,week); WriteInstruction(0x80+15); } } } if(s4==0) //保存并退出 { s1num=0; WriteInstruction(0x0c); TR0=1; } } } void main(void) { uchar k=0; LcdInitiate(); //調(diào)用LCD初始化函數(shù) while(1) { keyscan(); k=1; } } void timer0() interrupt 1 { count++; if(count==13) { count=0; second++; if(second==60) //秒計(jì)滿(mǎn)60,秒歸0,分+1 { second=0; minute++; if(minute==60) //分計(jì)滿(mǎn)60,分歸0,時(shí)+1 { minute=0; hour++; if(hour==24) //時(shí)計(jì)滿(mǎn)24,時(shí)歸0,星期+1,日+1 { hour=0; week++; day++; if(week==8) week=1; //星期計(jì)滿(mǎn)7,星期歸1 if(month==1||month==3||month==5||month==7||month==8||month==10||month==12)//大月三十一天 { if(day==32) //大月天數(shù)計(jì)滿(mǎn)31,日歸1,月+1 { day=1; month++; } } if(month==4||month==6||month==9||month==11) //小月三十天 { if(day==31) //小月天數(shù)計(jì)滿(mǎn)30,日歸1,月+1 { day=1; month++; } } if(month==2) { if(leap_year()) { if(day==30) //閏年二月29天計(jì)滿(mǎn),日歸1,月+1 { day=1; month++; } } else { if(day==29) //非閏年二月28天計(jì)滿(mǎn),日歸1,月+1 { day=1; month++; } } } if(month==13) //月計(jì)滿(mǎn)12,月歸1,年+1 { month=1; year++; if(year==99) //年計(jì)滿(mǎn)99,年歸0 { year=0; } write_nyr(2,year); } write_nyr(5,month); } write_nyr(8,day); write_week(15,week); } write_sfm(6,hour); } write_sfm(9,minute); } write_sfm(12,second); }
|