長(zhǎng)春工業(yè)大學(xué) 測(cè)控技術(shù)與儀器專業(yè) 單片機(jī)LCD1602顯示年月日時(shí)鐘帶星期和鬧鐘,可識(shí)別閏年 下載文檔即可完全復(fù)制 #include <reg52.h> #define uchar unsigned char #define uint unsigned int sbit lcdrs =P0^7; //液晶引腳定義 sbit led_cs = P0^6; sbit lcden =P0^5; sbit boom =P3^6; sbit key1 = P3^5; sbit key2 = P3^4; sbit key3 = P3^3; sbit keyE = P3^2; ucharnum,key1num,key2num,count,hour,min,sec,day,mon,year,shi,fen,miao,week; char ye1,ye2; uchar code cg_1602[]={0x08,0x0f,0x12,0x0f,0x0a,0x1f,0x02,0x02, 0x0f,0x09,0x0f,0x09,0x0f,0x09,0x11,0x00, 0x0f,0x09,0x09,0x0f,0x09,0x09,0x0f,0x00, 0x08,0x0f,0x12,0x0f,0x0a,0x1f,0x02,0x02,};//"年月日" /*延時(shí)函數(shù)*/ void delay(uint xms) { uint i,j; for(i=xms;i>0;i--) for(j=114;j>0;j--); } /*1602液晶*/ void write_com(uchar com)//寫命令 { lcdrs=0; lcden=0; P0=com; delay(5); lcden=1; delay(5); lcden=0; } void write_data(uchar date)//寫數(shù)據(jù) { lcdrs=1; lcden=0; P0=date; delay(5); lcden=1; delay(5); lcden=0; } void write_by_xy(uchar x,uchar y)//坐標(biāo)定位 { ucharaddress; if(y==0) address=0x80+x;//y=0,寫第一行 else address=0xc0+x;//y=1,寫第二行 write_com(address); } /*void write_char(uchar x,uchar y,uchar date)//坐標(biāo)定位顯示 { write_by_xy(x,y);//先定位 write_data(date);//后寫數(shù) }*/ void write_string(uchar x,uchar y,uchar *s)//寫字符串 { write_by_xy(x,y);//設(shè)定顯示位置 while(*s)//writecharacter { P0=*s; write_data(*s); s++; } } void write_sfm(uchar add,uchar date)//寫時(shí)分秒函數(shù) { ucharhour,ge; hour=date/10;//分解一個(gè)2位數(shù)的十位和個(gè)位 ge=date%10; write_com(0x80+add);//設(shè)置顯示位置 write_data(0x30+hour);//送去液晶顯示十位 write_data(0x30+ge);//送去液晶顯示個(gè)位 } void write_cg()//寫入固定漢字和符號(hào) { write_com(0x40);//設(shè)定CGRAM地址 for(num=0;num<24;num++)//將自定義字型碼寫入CGRAM中 { write_data(cg_1602[num]); } write_com(0xc4);//年 { write_data(0); } write_com(0xc7);//月 { write_data(1); } write_com(0xca);//日 { write_data(2); } write_string(2,0,":"); write_string(5,0,":"); write_string(0x0a,0,":"); write_string(0x0d,0,":"); write_string(0x0c,1,"W"); write_string(0x0d,1,"K"); } void init_1602()//初始化 { led_cs=0; hour=23;min=59;sec=55;key1num=0;count=0;day=28;mon=2;ye1=20;ye2=13;year=ye1*100+ye2;boom=0;shi=0;fen=0;miao=0;week=7; write_com(0x38); write_com(0x0c); write_com(0x06); write_com(0x01); write_string(0,1,"2013"); write_string(5,1,"02"); write_string(8,1,"28"); write_sfm(8,shi); write_sfm(0x0b,fen); write_sfm(0x0e,miao); write_sfm(0,hour); write_sfm(3,min); write_sfm(6,sec); write_sfm(0x48,day); write_sfm(0x45,mon); write_sfm(0x40,ye1); write_sfm(0x42,ye2); write_sfm(0x4e,week); write_cg(); TMOD=0x01;//設(shè)置定時(shí)器0工作模式1 TH0=(65536-50000)/256;//定時(shí)器裝初值 TL0=(65536-50000)%256; EA=1; //開(kāi)總中斷 ET0=1; //開(kāi)定時(shí)器0中斷 TR0=1; //啟動(dòng)定時(shí)器0 } /*鍵盤掃描函數(shù)*/ void keyscan()//按鍵掃描函數(shù) { //keyE =0; if(key1==0) { delay(5); if(key1==0)//確認(rèn)功能鍵被按下 { key1num++;//功能鍵按下次數(shù)記錄 while(!key1);//釋放確認(rèn) if(key1num==1)//第一次被按下時(shí) { TR0=0;//關(guān)閉定時(shí)器 write_com(0x80+7);//光標(biāo)定位到秒位置 write_com(0x0f);//光標(biāo)開(kāi)始閃爍 } if(key1num==2)//第二次按下光標(biāo)閃爍定位到分鐘位置 { write_com(0x80+4); } if(key1num==3)//第三次按下光標(biāo)閃爍定位到小時(shí)位置 { write_com(0x80+1); } if(key1num==4)//第四次按下光標(biāo)閃爍定位到日位置 { write_com(0x80+0x49); } if(key1num==5)//第五次按下光標(biāo)閃爍定位到月位置 { write_com(0x80+0x46); } if(key1num==6)//第六次按下光標(biāo)閃爍定位到年2位置 { write_com(0x80+0x43); } if(key1num==7)//第七次按下光標(biāo)閃爍定位到年1位置 { write_com(0x80+0x41); } if(key1num==8)//第八次按下光標(biāo)閃爍定位到星期位置 { write_com(0x80+0x4f); } if(key1num==9)//第九次按下 { key1num=0;//記錄按鍵數(shù)清零 write_com(0x0c);//取消光標(biāo)閃爍 TR0=1;//啟動(dòng)定時(shí)器使時(shí)鐘開(kāi)始走 } } } if(key1num!=0)//只有功能鍵被按下后,增加和減小鍵才有效 { if(key2==0) { delay(5); if(key2==0)//增加鍵確認(rèn)被按下 { while(!key2);//按鍵釋放 if(key1num==1)//若功能鍵第一次按下 { sec++;//則調(diào)整秒加1 if(sec==60)//若滿60后將清零 sec=0; write_sfm(6,sec);//每調(diào)節(jié)一次送液晶顯示一下 write_com(0x80+7);//顯示位置重新回到調(diào)節(jié)處 } if(key1num==2)//若功能鍵第二次按下 { min++;//則調(diào)整分鐘加1 if(min==60)//若滿60后將清零 min=0; write_sfm(3,min);//每調(diào)節(jié)一次送液晶顯示一下 write_com(0x80+4);//顯示位置重新回到調(diào)節(jié)處 } if(key1num==3)//若功能鍵第三次按下 { hour++;//則調(diào)整小時(shí)加1 if(hour==24)//若滿24后將清零 hour=0; write_sfm(0,hour);;//每調(diào)節(jié)一次送液晶顯示一下 write_com(0x80+1);//顯示位置重新回到調(diào)節(jié)處 } if(key1num==4)//若功能鍵第四次按下 { day++;//則調(diào)整日加1 if(day>31)//若大于31后將置一 day=1; write_sfm(0x48,day);//每調(diào)節(jié)一次送液晶顯示一下 write_com(0x80+0x48);//顯示位置重新回到調(diào)節(jié)處 } if(key1num==5)//若功能鍵第五次按下 { mon++;//則調(diào)整月加1 if(mon>12)//若大于12后將置一 mon=1; write_sfm(0x45,mon);//每調(diào)節(jié)一次送液晶顯示一下 write_com(0x80+0x45);//顯示位置重新回到調(diào)節(jié)處 } if(key1num==6)//若功能鍵第六次按下 { ye2++;//則調(diào)整年加1 if(ye2==0x0a)//若滿99后將清零 ye2=0; year=ye1*100+ye2; write_sfm(0x42,ye2);//每調(diào)節(jié)一次送液晶顯示一下 write_com(0x80+0x42);//顯示位置重新回到調(diào)節(jié)處 } if(key1num==7)//若功能鍵第七次按下 { ye1++;//則調(diào)整年加100 if(ye1==0x0a)//若滿99后將清零 ye1=0; year=ye1*100+ye2; write_sfm(0x40,ye1);//每調(diào)節(jié)一次送液晶顯示一下 write_com(0x80+0x40);//顯示位置重新回到調(diào)節(jié)處 } if(key1num==8)//若功能鍵第八次按下 { week++;//則調(diào)整周加一 if(week>7)//若大于7后置一 week=1; write_sfm(0x4f,week);//每調(diào)節(jié)一次送液晶顯示一下 write_com(0x80+0x4f);//顯示位置重新回到調(diào)節(jié)處 } } } if(key3==0) { delay(5); if(key3==0)//確認(rèn)減小鍵被按下 { while(!key3);//按鍵釋放 if(key1num==1)//若功能鍵第一次按下 { sec--;//則調(diào)整秒減1 if(sec==-1)//若減到負(fù)數(shù)則將其重新設(shè)置為59 sec=59; write_sfm(6,sec);//每調(diào)節(jié)一次送液晶顯示一下 write_com(0x80+7);//顯示位置重新回到調(diào)節(jié)處 } if(key1num==2)//若功能鍵第二次按下 { min--;//則調(diào)整分鐘減1 if(min==-1)//若減到負(fù)數(shù)則將其重新設(shè)置為59 min=59; write_sfm(3,min);//每調(diào)節(jié)一次送液晶顯示一下 write_com(0x80+4);//顯示位置重新回到調(diào)節(jié)處 } if(key1num==3)//若功能鍵第三次按下 { hour--;//則調(diào)整小時(shí)減1 if(hour==-1)//若減到負(fù)數(shù)則將其重新設(shè)置為23 hour=23; write_sfm(0,hour);//每調(diào)節(jié)一次送液晶顯示一下 write_com(0x80+1);//顯示位置重新回到調(diào)節(jié)處 } if(key1num==4)//若功能鍵第四次按下 { day--;//則調(diào)整日減1 if(day==0)//若日為零時(shí)將置一 day=31; write_sfm(0x48,day);//每調(diào)節(jié)一次送液晶顯示一下 write_com(0x80+0x49);//顯示位置重新回到調(diào)節(jié)處 } if(key1num==5)//若功能鍵第五次按下 { mon--;//則調(diào)整月減1 if(mon==0)//若月為零將置一 mon=12; write_sfm(0x45,mon);//每調(diào)節(jié)一次送液晶顯示一下 write_com(0x80+0x45);//顯示位置重新回到調(diào)節(jié)處 } if(key1num==6)//若功能鍵第六次按下 { ye2--;//則調(diào)整年減1 if(ye2<0)//若小于零后將設(shè)置為99 ye2=99; year=ye1*100+ye2; write_sfm(0x42,ye2);//每調(diào)節(jié)一次送液晶顯示一下 write_com(0x80+0x42);//顯示位置重新回到調(diào)節(jié)處 } if(key1num==7)//若功能鍵第七次按下 { ye1--;//則調(diào)整年減100 if(ye1<0)//若小于零后將設(shè)置為99 ye1=99; year=ye1*100+ye2; write_sfm(0x40,ye1);//每調(diào)節(jié)一次送液晶顯示一下 write_com(0x80+0x40);//顯示位置重新回到調(diào)節(jié)處 } if(key1num==8)//若功能鍵第八次按下 { week--;//則調(diào)整周減一 if(week==0)//若等于0后將置7 week=7; write_sfm(0x4f,week);//每調(diào)節(jié)一次送液晶顯示一下 write_com(0x80+0x4f);//顯示位置重新回到調(diào)節(jié)處 } } } } if(keyE==0) { delay(5); if(keyE==0)//確認(rèn)功能鍵被按下 { key2num++;//功能鍵按下次數(shù)記錄 while(!keyE);//釋放確認(rèn) if(key2num==1)//第一次被按下時(shí) { TR0=0;//關(guān)閉定時(shí)器 write_com(0x80+0x0f);//光標(biāo)定位到秒位置 write_com(0x0f);//光標(biāo)開(kāi)始閃爍 } if(key2num==2)//第二次按下光標(biāo)閃爍定位到分鐘位置 { write_com(0x80+0x0c); } if(key2num==3)//第三次按下光標(biāo)閃爍定位到小時(shí)位置 { write_com(0x80+9); } if(key2num==4)//第八次按下 { key2num=0;//記錄按鍵數(shù)清零 write_com(0x0c);//取消光標(biāo)閃爍 TR0=1;//啟動(dòng)定時(shí)器使時(shí)鐘開(kāi)始走 } } } if(key2num!=0)//只有功能鍵被按下后,增加和減小鍵才有效 { if(key2==0) { delay(5); if(key2==0)//增加鍵確認(rèn)被按下 { while(!key2);//按鍵釋放 if(key2num==1)//若功能鍵第一次按下 { miao++;//則調(diào)整秒加1 if(miao==60)//若滿60后將清零 miao=0; write_sfm(0x0e,miao);//每調(diào)節(jié)一次送液晶顯示一下 write_com(0x80+0x0e);//顯示位置重新回到調(diào)節(jié)處 } if(key2num==2)//若功能鍵第二次按下 { fen++;//則調(diào)整分鐘加1 if(fen==60)//若滿60后將清零 fen=0; write_sfm(0x0b,fen);//每調(diào)節(jié)一次送液晶顯示一下 write_com(0x80+0x0b);//顯示位置重新回到調(diào)節(jié)處 } if(key2num==3)//若功能鍵第三次按下 { shi++;//則調(diào)整小時(shí)加1 if(shi==24)//若滿24后將清零 shi=0; write_sfm(8,shi);;//每調(diào)節(jié)一次送液晶顯示一下 write_com(0x80+8);//顯示位置重新回到調(diào)節(jié)處 } } } if(key3==0) { delay(5); if(key3==0)//確認(rèn)減小鍵被按下 { while(!key3);//按鍵釋放 if(key2num==1)//若功能鍵第一次按下 { miao--;//則調(diào)整秒減1 if(miao==-1)//若減到負(fù)數(shù)則將其重新設(shè)置為59 miao=59; write_sfm(0x0e,miao);//每調(diào)節(jié)一次送液晶顯示一下 write_com(0x80+0x0e);//顯示位置重新回到調(diào)節(jié)處 } if(key2num==2)//若功能鍵第二次按下 { fen--;//則調(diào)整分鐘減1 if(fen==-1)//若減到負(fù)數(shù)則將其重新設(shè)置為59 fen=59; write_sfm(0x0b,fen);//每調(diào)節(jié)一次送液晶顯示一下 write_com(0x80+0x0b);//顯示位置重新回到調(diào)節(jié)處 } if(key2num==3)//若功能鍵第三次按下 { shi--;//則調(diào)整小時(shí)減1 if(shi==-1)//若減到負(fù)數(shù)則將其重新設(shè)置為23 shi=23; write_sfm(8,shi);//每調(diào)節(jié)一次送液晶顯示一下 write_com(0x80+8);//顯示位置重新回到調(diào)節(jié)處 } } } } } /*主函數(shù)*/ void main() { led_cs=0; init_1602(); while(1) { keyscan(); } } /*中斷函數(shù)*/ void timer0() interrupt 1//定時(shí)器0中斷服務(wù)程序 { TH0=(65536-50000)/256;//再次裝定時(shí)器初值 TL0=(65536-50000)%256; count++;//中斷次數(shù)累加 if(count==20)//20次50毫秒為1秒 { count=0; sec++; if(sec==60)//秒加到60則進(jìn)位分鐘 { sec=0;//同時(shí)秒數(shù)清零 min++; if(min==60)//分鐘加到60則進(jìn)位小時(shí) { min=0;//同時(shí)分鐘數(shù)清零 hour++; //boom=1; //delay(5); //boom=0; if(hour==24)//小時(shí)加到24則小時(shí)清零 { hour=0; day++; week++; if(week>7) { week=1; } if(mon==1) { if(day>31) { day=1; mon++; } } if(mon==2) { if((year%4==0 &&year%100!=0)||year%4==0) { if(day>29) { day=1; mon++; } } else if(day>28) { day=1; mon++; } } if(mon==3) { if(day>31) { day=1; mon++; } } if(mon==4) { if(day>30) { day=1; mon++; } } if(mon==5) { if(day>31) { day=1; mon++; } } if(mon==6) { if(day>30) { day=1; mon++; } } if(mon==7) { if(day>31) { day=1; mon++; } } if(mon==8) { if(day>31) { day=1; mon++; } }if(mon==9) { if(day>30) { day=1; mon++; } } if(mon==10) { if(day>31) { day=1; mon++; } } if(mon==11) { if(day>30) { day=1; mon++; } } if(mon==12) { if(day>31) { day=1; mon=1; ye2++; } } } write_sfm(0x4e,week); write_sfm(0x48,day); write_sfm(0x45,mon); write_sfm(0x40,ye1); write_sfm(0x42,ye2); } write_sfm(0,hour);//小時(shí)若變化則重新寫入 } write_sfm(3,min);//分鐘若變化則重新寫入 } write_sfm(6,sec);//秒若變化則重新寫入 if((hour==shi&& min==fen) && sec==miao) { boom=1; delay(5); boom=0; } }
|