基于单片机的带有日历功能的数字时钟
功能:
1.年、月、日,以及24小时制时间显示,均可调
2.自动判断是否闰年以及闰月,理论上至2100年
//去年写的,感觉以后要经常打理自己的博客,与众多Coder分享交流,所以现在才拿出来,多多包含
#include<reg51.h> #define uint unsigned int #define uchar unsigned char #define LCD1602_DATAPINS P0
uchar code table[]=" 2016-01-01 SUN"; uchar code table1[]=" 23:59:54"; uchar count=0; uchar shi=23,fen=59,miao=54,nian=16,yue=1,ri=1; uchar k1_num=0;//k1/k2/k3按下的次数
//按键 sbit k1=P1^1;//功能键 sbit k2=P1^2;//加 sbit k3=P1^3;//减
<pre name="code" class="cpp">void Delay1us(uint a); void LCD1602_WriteCom(uchar com);/*LCD1602写入8位命令子函数*/ void LCD1602_WriteData(uchar dat); /*LCD1602写入8位数据子函数*/ void LCD1602_Init();/*LCD1602初始化子程序*/ void Delay1us(uint a) { uint b,c; for(c=a;c>0;c--) for(b=110;b>0;b--); } void LCD1602_WriteCom(uchar com) //写入命令 { LCD1602_E=0; LCD1602_RS=0; LCD1602_RW=0; LCD1602_DATAPINS=com; Delay1us(10); LCD1602_E=1; Delay1us(10); LCD1602_E=0; } void LCD1602_WriteData(uchar dat) //写入数据 { LCD1602_E=0; LCD1602_RS=1; LCD1602_RW=0; LCD1602_DATAPINS=dat; Delay1us(10); LCD1602_E=1; Delay1us(10); LCD1602_E=0; } void LCD1602_Init() //LCD初始化子程序 { uint num; LCD1602_WriteCom(0x38); //开显示 LCD1602_WriteCom(0x0c); //开显示不显示光标 LCD1602_WriteCom(0x06); //写一个指针加1 LCD1602_WriteCom(0x01); //清屏 LCD1602_WriteCom(0x80); //设置数据指针起点 for (num=0;num<15;num++) { LCD1602_WriteData(table[num]); Delay1us(10); } LCD1602_WriteCom(0x80+0x40); for (num=0;num<11;num++) { LCD1602_WriteData(table1[num]); Delay1us(10); } TMOD=0X01; TH0=(65536-50000)/256; TL0=(65536-50000)%256; EA=1;//总中断 ET0=1; TR0=1; } void LCD1602_WriteSFM(uchar add,uchar dat) { uchar shi,ge; shi=dat/10; ge=dat%10; LCD1602_WriteCom(0x80+0x40+add); LCD1602_WriteData(0x30+shi);//根据字符手册,写十位 LCD1602_WriteData(0x30+ge);//根据字符手册,写个位 } void LCD1602_WriteNYR(uchar add,uchar dat) { uchar shi,ge; shi=dat/10; ge=dat%10; LCD1602_WriteCom(0x80+add); LCD1602_WriteData(0x30+shi);//根据字符手册,写十位 LCD1602_WriteData(0x30+ge);//根据字符手册,写个位 } void keyscan() { //k1键指令 if(k1==0) { Delay1us(10); if(k1==0) { k1_num++; while(!k1); if(k1_num==1) { TR0=0; LCD1602_WriteCom(0x80+0x40+11); LCD1602_WriteCom(0x0f); } } if(k1_num==2) { LCD1602_WriteCom(0x80+0x40+8); } if(k1_num==3) { LCD1602_WriteCom(0x80+0x40+5); } if(k1_num==4)//跳转到日 { LCD1602_WriteCom(0x80+10); } if(k1_num==5)//跳转到月 { LCD1602_WriteCom(0x80+7); } if(k1_num==6)//跳转到年 { LCD1602_WriteCom(0x80+4); } if(k1_num==7) { k1_num=0; LCD1602_WriteCom(0x0c); if (yue==4||yue==6||yue==9||yue==11) //防止调时间出现某月的日期超过最大值 { if (ri>30) ri=30; LCD1602_WriteNYR(9,ri); } else if (yue==1||yue==3||yue==5||yue==7||yue==8||yue==10||yue==12) { if (ri>31) ri=31; LCD1602_WriteNYR(9,ri); } else if (yue==2) { if (nian%4==0) { if (ri>29) ri=29; } else { if (ri>28) ri=28; } LCD1602_WriteNYR(9,ri); } TR0=1; } } if(k1_num!=0) { //k2键指令 if(k2==0) { Delay1us(5); if(k2==0) { while(!k2); if(k1_num==1) { miao++; if(miao==60) miao=0; LCD1602_WriteSFM(10,miao); LCD1602_WriteCom(0x80+0x40+11); } if(k1_num==2) //分 { fen++; if(fen==60) fen=0; LCD1602_WriteSFM(7,fen); LCD1602_WriteCom(0x80+0x40+8); } if(k1_num==3)//时 { shi++; if(shi==24) shi=0; LCD1602_WriteSFM(4,shi); LCD1602_WriteCom(0x80+0x40+5); } if(k1_num==4)//日 { ri++; if (yue==4||yue==6||yue==9||yue==11) { if(ri==31) ri=1; } else if (yue==1||yue==3||yue==5||yue==7||yue==8||yue==10||yue==12) { if (ri==32) ri=1; } else if (yue==2) { if (nian%4==0)//闰年 { if (ri==30) ri=1; } else { if (ri==29) ri=1; } } LCD1602_WriteNYR(9,ri); LCD1602_WriteCom(0x80+10); //光标前移一位 } if(k1_num==5)//月 { yue++; if(yue==13) yue=1; LCD1602_WriteNYR(6,yue); LCD1602_WriteCom(0x80+7); //光标前移一位 } if(k1_num==6)//年 { nian++; if(nian==100) nian=0; LCD1602_WriteNYR(3,nian); LCD1602_WriteCom(0x80+4); //光标前移一位 } } } //k3键指令 if(k3==0) { Delay1us(10); if(k3==0) { while(!k3); if(k1_num==1) { miao--; if(miao==-1) miao=59; LCD1602_WriteSFM(10,miao); LCD1602_WriteCom(0x80+0x40+11); } if(k1_num==2) { fen--; if(fen==-1) fen=59; LCD1602_WriteSFM(7,fen); LCD1602_WriteCom(0x80+0x40+8); } if(k1_num==3) { shi--; if(shi==-1) shi=23; LCD1602_WriteSFM(4,shi); LCD1602_WriteCom(0x80+0x40+5); } if(k1_num==4)//日 { ri--; if(ri==0) if (yue==4||yue==6||yue==9||yue==11) ri=30; else if (yue==1||yue==3||yue==5||yue==7||yue==8||yue==10||yue==12) ri=31; else if (yue==2) if (nian%4==0) ri=29; else ri=28; LCD1602_WriteNYR(9,ri); LCD1602_WriteCom(0x80+10); //光标前移一位 } if(k1_num==5)//月 { yue--; if(yue==0) yue=12; LCD1602_WriteNYR(6,yue); LCD1602_WriteCom(0x80+7); //光标前移一位 } if(k1_num==6)//年 { nian--; if(nian==-1) nian=99; LCD1602_WriteNYR(3,nian); LCD1602_WriteCom(0x80+4); //光标前移一位 } } } } } void main() { LCD1602_Init(); while (1) { keyscan () ; if (count==20)//满一秒 { count=0; miao++; if (miao==60) { miao=0; fen++; if (fen==60) { fen=0; shi++; if (shi==24) { shi=0; ri++; if (yue==4||yue==6||yue==9||yue==11) { if (ri==31) { ri=1; yue++; if (yue==13) { yue=1; nian++; if (nian==100) nian=0; LCD1602_WriteNYR(3,nian); } LCD1602_WriteNYR(6,yue); } } else if (yue==1||yue==3||yue==5||yue==7||yue==8||yue==10||yue==12) { if (ri==32) { ri=1; yue++; if (yue==13) { yue=1; nian++; if (nian==100) nian=0; LCD1602_WriteNYR(3,nian); } LCD1602_WriteNYR(6,yue); } } else if (yue==2) { if (nian%4==0)//公元2000~2099之间的闰年 { if (ri==30) { ri=1; yue++; if (yue==13) { yue=1; nian++; if (nian==100) nian=0; LCD1602_WriteNYR(3,nian); } LCD1602_WriteNYR(6,yue); } } else { if (ri==29) { ri=1; yue++; if (yue==13) { yue=1; nian++; if (nian==100) nian=0; LCD1602_WriteNYR(3,nian); } LCD1602_WriteNYR(6,yue); } } } LCD1602_WriteNYR(9,ri); } LCD1602_WriteSFM(4,shi); } LCD1602_WriteSFM(7,fen); } LCD1602_WriteSFM(10,miao); } } } void timer0() interrupt 1 { TH0=(65536-50000)/256; TL0=(65536-50000)%256; count++; }