1、 日历功能 A、在此功能执行时,不可影响电子表的正常运行。 B、该模式下可显示年、月、日。 C、使用矩阵键盘调节时间。 D、满足特殊月份31、28天规律。 E、满足闰年规律。 2、 秒表功能 A、在此功能执行时,不可影响电子表的正常运行。 B、该模式下可实现秒表计时功能。 C、用一根杜邦线(结合程序)插入所需引脚,使得秒表停止计时,拔下杜邦线可继续计时(此要求下允许电子钟非正常运行,但不得人为不关闭任何定时器)。 3、定时功能 A、在此功能执行时,不可影响电子表的正常运行。
单片机源程序如下:
- #include<reg52.h>
- #define uchar unsigned char
- #define uint unsigned int
- uint year,year1;
- uchar code table[]={"2018-11-07week3"};
- uchar code table1[]={"19:29:55 "};
- uchar code table2[]={"0:00:00 "};
- sbit lcden=P3^4; //定义液晶使能端
- sbit lcdrs=P3^5; //液晶数据命令选择端
- sbit rw=P3^6; //定义读写选择
- sbit k0=P3^5;
- sbit dula=P2^6; //声明U1锁存端,锁存器
- sbit wela=P2^7; //声明U2锁存端,锁存器
- sbit beep=P2^3;
- uchar num,num1,a,a2,b,du,shi,shi1,fen,miao,ge,day,mon,week;
- uchar flag,flag1,shi,shi2,fen1,miao1,a1,du1,qie,du2,num3,num4;
- void delay(uint z)
- {
- uint x,y;
- for(x=z;x>0;x--)
- for(y=110;y>0;y--);
- }
- void write_com(uchar com) //写命令操作
- {
- rw=0;
- lcdrs=0; //选择写命令模式
- P0=com; //将要写的命令字,送到数据总线上
- delay(5); //稍作延时以待数据稳定
- lcden=1; //使能端,给一高脉冲,因为初始化函数,已经将使能端置为0
- delay(5); //稍作延时
- lcden=0; //使能端0完成高脉冲
- }
- void write_data(uint date1) //写数据操作
- {
- rw=0;
- lcdrs=1;
- P0=date1; //写数据
- delay(5);
- lcden=1;
- delay(5);
- lcden=0;
- }
- void write_sfm(uchar add,uint date1) //定义小时,分钟,秒的地址和数据
- {
- uchar shi,ge;
- shi=date1/10; //将数据分离
- ge=date1%10;
- write_com(0x80+0x40+add);//第二行数据指针位置调整
- write_data(0x30+shi); //更改显示数据的十位
- write_data(0x30+ge); //更改显示数据的个位
- }
- void write_md(uchar add,uint date1) //定义月份和天地址和数据
- {
- uchar shi,ge;
- shi=date1/10; //将数据分离
- ge=date1%10;
- write_com(0x80+add); //第一行数据指针位置调整
- write_data(0x30+shi); //更改显示数据的十位
- write_data(0x30+ge); //更改显示数据的个位
- }
- void write_y(uchar add,uint date1) //定义年地址和数据
- {
- uchar qian,bai,shi,ge;
- qian=date1/1000;
- bai=date1%1000/100;
- shi=date1%100/10; //将数据分离
- ge=date1%10;
- write_com(0x80+add);//第一行数据指针位置调整
- write_data(0x30+qian); //更改显示数据的千位
- write_data(0x30+bai); //更改显示数据的百位
- write_data(0x30+shi); //更改显示数据的十位
- write_data(0x30+ge); //更改显示数据的个位
- }
- //void zhuanhua()
- //{
- // switch(week)
- // {
- // case 1:
- // write_com(0x80+0x40+9);
- // write_data('M'); delay(5);
- // write_data('o'); delay(5);
- // write_data('n'); delay(5);
- // write_data('d'); delay(5);
- // write_data('a'); delay(5);
- // write_data('y'); delay(5);
- // write_data(' ');
- // break;
- // case 2:
- // write_com(0x80+0x40+9);
- // write_data('T'); delay(5);
- // write_data('u'); delay(5);
- // write_data('e'); delay(5);
- // write_data('s'); delay(5);
- // write_data('d'); delay(5);
- // write_data('a'); delay(5);
- // write_data('y');
- // break;
- // case 3:
- // write_com(0x80+0x40+9);
- // write_data('W'); delay(5);
- // write_data('e'); delay(5);
- // write_data('d'); delay(5);
- // write_data('n'); delay(5);
- // write_data('e'); delay(5);
- // write_data('s'); delay(5);
- // write_data('d');
- // break;
- // case 4:
- // write_com(0x80+0x40+9);
- // write_data('T'); delay(5);
- // write_data('h'); delay(5);
- // write_data('u'); delay(5);
- // write_data('r'); delay(5);
- // write_data('s'); delay(5);
- // write_data('d'); delay(5);
- // write_data('a');
- // break;
- // case 5:
- // write_com(0x80+0x40+9);
- // write_data('F'); delay(5);
- // write_data('r'); delay(5);
- // write_data('i'); delay(5);
- // write_data('d'); delay(5);
- // write_data('a'); delay(5);
- // write_data('y'); delay(5);
- // write_data(' ');
- // break;
- // case 6:
- // write_com(0x80+0x40+9);
- // write_data('S'); delay(5);
- // write_data('a'); delay(5);
- // write_data('t'); delay(5);
- // write_data('u'); delay(5);
- // write_data('r'); delay(5);
- // write_data('d'); delay(5);
- // write_data('a');
- // break;
- // case 7:
- // write_com(0x80+0x40+9);
- // write_data('S'); delay(5);
- // write_data('u'); delay(5);
- // write_data('n'); delay(5);
- // write_data('d'); delay(5);
- // write_data('a'); delay(5);
- // write_data('y'); delay(5);
- // write_data(' ');
- // break;
- // }
- //}
- void jianpan()
- {
- uchar temp;
- P3=0xfe;
- temp=P3;
- temp=temp&0xf0;
- if(temp!=0xf0)
- {
- delay(10);
- temp=P3;
- temp=temp&0xf0;
- if(temp!=0xf0)
- {
- temp=P3;
- switch(temp)
- {
- case 0xee: //显示需要更改地方的光标
- du++;
- while(temp!=0xf0) //按键释放,使每按一次只增加一个数
- {
- temp=P3;
- temp=temp&0xf0;
- }
- if(du==1) //移动光标至秒位置,同时暂停计时
- {
- TR0=0;
- write_com(0x80+0x40+6);
- write_com(0x0f); //显示光标
- }
- if(du==2) //移动光标至分位置
- {
- write_com(0x80+0x40+3);
- }
- if(du==3) //移动光标至时位置
- {
- write_com(0x80+0x40+0);
- }
- if(du==4) //移动光标至天位置
- {
- write_com(0x80+8);
- }
- if(du==5) //移动光标至月位置
- {
- write_com(0x80+5);
- }
- if(du==6) //移动光标至年位置,用于 增加年份
- {
- write_com(0x80+0);
- }
- if(du==7) //移动光标至周位置
- {
- write_com(0x80+14); //先送地址
- // write_data(0x30+week); //输入的数字
- }
- if(du==8) //移动光标至年位置 减少年份
- {
- write_com(0x80+0);
- }
- if(du==9) //使du循环,恢复定时器
- {
- TR0=1;
- du=0;
- write_com(0x80+0x40+10);
- write_com(0x0c); //关光标
- }
-
- break;
- case 0xde:
- while(temp!=0xf0) //按键释放
- {
- temp=P3;
- temp=temp&0xf0;
- }
- if(du==1) //在秒位置时,使秒增加
- {
- miao++;
- if(miao==60)
- {
- miao=0;
- }
- write_sfm(6,miao); //更新秒位置数据
- }
- if(du==2) //在分位置时,使分增加
- {
- fen++;
- if(fen==60)
- {
- fen=0;
- }
- write_sfm(3,fen); //更新秒位置数据
- }
- if(du==3) //在小时位置时,使小时增加
- {
- shi++;
- if(shi==24)
- {
- shi=0;
- }
- if(flag1==0) //显示24小时模式
- {
- write_sfm(0,shi);
- }
- if(flag1==1) //显示12小时模式
- {
- if(shi==0)
- {
- shi=12;
- }
- if((shi<=12)&&(shi>=1))
- {
- shi1=shi;
- }
- if(shi>12)
- {
- shi1=shi-12;
- }
- write_sfm(0,shi1); //更新12小时模式的数据
- write_com(0x80+0x40+0);
- }
- }
- if(du==4) //在天位置时,使天增加
- {
- day++;
- if(year%4==0&&year%10!=0) //如果是闰年
- {
- if(mon==2)
- {
- if(day==30)
- {
- day=1;
- }
- }
- }
- if((year%4==0&&year%100==0)||(year%4!=0)) //如果不是闰年
- {
- if(mon==2)
- {
- if(day==29)
- {
- day=1;
- }
- }
- }
-
- if(mon==1||mon==3||mon==5||mon==7||mon==8||mon==10||mon==12)
- {
- if(day==32)
- {
- day=1;
- }
- }
- if(mon==4||mon==6||mon==9||mon==11)
- {
- if(day==31)
- {
- day=1;
- }
- }
- write_md(8,day);
- }
- if(du==5) //在月位置时,使月增加
- {
- mon++;
- if(mon==13)
- {
- mon=1;
- }
- write_md(5,mon);
- }
- if(du==6) //在年位置时,使年增加
- {
- year++;
- write_y(0,year);
- }
- if(du==7) //在周位置时,使周增加
- {
- week++;
- if(week==8)
- {
- week=1;
- }
- write_com(0x80+14); //位置
- write_data(0x30+week); //显示数据
- }
- if(du==8) //在天位置时,使年减少
- {
- year--;
- write_y(0,year);
- }
- break;
- case 0xbe:
- flag1++; //使变量flag1++
- while(temp!=0xf0)
- {
- temp=P3;
- temp=temp&0xf0;
- }
- if(flag1==1) //如果变量flag1为1那么进行12小时模式
- {
- if(shi==0)
- {
- shi=12;
- }
- if((shi<=12)&&(shi>=1))
- {
- write_com(0x80+0x40+8);
- write_data('+');
- shi1=shi;
- }
- if(shi>12)
- {
- write_com(0x80+0x40+8);
- write_data('-');
- shi1=shi-12;
- }
- write_sfm(0,shi1);
- write_com(0x80+0x40+0);
- }
- if(flag1>=2)
- {
- flag1=0;
- }
- if(flag1==0) //如果变量flag1为1那么进行24小时模式
- {
- write_sfm(0,shi);
- write_com(0x80+0x40+0);
- }
- break;
- case 0x7e:
- du1++; //使du1++
- while(temp!=0xf0)
- {
- temp=P3;
- temp=temp&0xf0;
- }
- if(du1==1) //使定时器1暂停,移动光标至秒表秒位
- {
- write_com(0x80+0x40+14);
- TR1=0;
- write_com(0x0f);//显示光标
- }
- if(du1==2) //移动光标至秒表 分 位
- {
- write_com(0x80+0x40+11);
- }
- if(du1==3) //时 位
- {
- write_com(0x80+0x40+9);
- }
- if(du1==4) //恢复定时器1,返回原位
- {
- write_com(0x80+0x40+14);
- TR1=1;
- write_com(0x0c); //关闭光标显示
- }
- if(du1==5)
- {
- du1=0;
- }
- break;
- }
- }
- }
- P3=0xfd;
- temp=P3;
- temp=temp&0xf0;
- if(temp!=0xf0)
- {
- delay(10);
- temp=P3;
- temp=temp&0xf0;
- if(temp!=0xf0)
- {
- temp=P3;
- switch(temp)
- {
- case 0xed:
- while(temp!=0xf0)
- {
- temp=P3;
- temp=temp&0xf0;
- }
- if(du1==1)
- {
- miao1++; //使秒表光标所在地 秒 加
- if(miao1==60)
- {
- miao1=0;
- }
- write_sfm(14,miao1); //更新
- }
- if(du1==2) //分 加
- {
- fen1++;
- if(fen1==60)
- {
- fen1=0;
- }
- write_sfm(11,fen1);
- }
- if(du1==3) //时 加
- {
- shi2++;
- if(shi2==60)
- {
- shi2=0;
- }
- write_com(0x80+0x40+9);//第二行数据指针位置调整
- write_data(0x30+shi2); //更改显示数据的个位
- }
- break;
- case 0xdd:
- TR1=1; //开启秒表(初始值正走)
- break;
- case 0xbd:
- qie=1; //切换 秒表 至倒计时
- break;
- case 0x7d:
- num4=0; //切换闹钟铃声 一直响
- break;
- }
- }
- }
- P3=0xfb;
- temp=P3;
- temp=temp&0xf0;
- if(temp!=0xf0)
- {
- delay(10);
- temp=P3;
- temp=temp&0xf0;
- if(temp!=0xf0)
- {
- temp=P3;
- switch(temp)
- {
- case 0xeb:
- num4=1; //切换闹钟铃声 间断响
- break;
- case 0xdb:
- qie=0; //切换 秒表 正计时
- break;
- case 0xbb:
- TR1=0; //使秒表停止计时
- break;
- }
- }
- }
- }
- void shixu1() //定时器1 秒表 正走时序
- {
- if(a1==20)
- {
- a1=0;
- miao1++;
- if(miao1==60)
- {
- miao1=0;
- fen1++;
- if(fen1==60)
- {
- fen1=0;
- shi2++;
-
- if(shi2==10)
- {
- shi2=0;
- }
- write_com(0x80+0x40+9);//第二行数据指针位置调整
- write_data(0x30+shi2); //更改显示数据的个位
- }
- write_sfm(11,fen1);
- }
- write_sfm(14,miao1);
- }
- }
- void shixu2() //定时器1 秒表 倒走时序
- {
- if(a1==20)
- {
- a1=0;
- miao1--;
- if(miao1==0&&fen1>=1&&shi2>=1) //如果在秒为0,时和分钟不为零的情况下
- {
- miao1=59;
- fen1--;
- if(fen1==0&&shi2>=1) //如果在分为0,分钟不为零的情况下
- {
- fen1=59;
- shi2--;
- write_com(0x80+0x40+9);//第二行数据指针位置调整
- write_data(0x30+shi2); //更改显示数据的个位
- }
- write_sfm(11,fen1);
- }
- write_sfm(14,miao1);
- }
- }
- void shixu() //日历走时序
- {
- if(a==20)
- {
- a=0;
- miao++;
- if(miao==60)
- {
- miao=0;
- fen++;
- if(fen==60)
- {
- fen=0;
- shi++;
- if(shi==24)
- {
- shi=0;
- day++;
- week++;
- if(week==7)
- {
- week=1;
- }
- if(year%4==0&&year%100!=0) //如果是闰年
- {
- if(mon==2)
- {
- if(day==30)
- {
- day=1;
- mon++;
-
- write_md(5,mon);
- }
- }
- }
- if((year%4==0&&year%100==0)||(year%4!=0)) //如果不是闰年
- {
- if(mon==29)
- {
- if(day==30)
- {
- day=1;
- mon++;
-
- write_md(5,mon);
- }
- }
- }
- if(mon==1||mon==3||mon==5||mon==7||mon==8||mon==10||mon==12)
- {
- if(day==32)
- {
- day=1;
- mon++;
-
- write_md(5,mon);
- }
- }
- if(mon==4||mon==6||mon==9||mon==11)
- {
- if(day==31)
- {
- day=1;
- mon++;
-
- write_md(5,mon);
- }
- }
-
- if(mon==13)
- {
- mon=1;
- year++;
- write_y(1,year);
- }
- write_com(0x80+14); //位置
- write_data(0x30+week); //显示数据
- // zhuanhua();
- write_md(8,day);
- }
- if(flag1==0) //切换至24小时模式
- {
- write_sfm(0,shi);
- }
- if(flag1==1) //切换至12小时模式
- {
- if(shi==0)
- {
- shi=12;
- }
- if((shi<=12)&&(shi>=1))
- {
- shi1=shi;
- }
- if(shi>12)
- {
- shi1=shi-12;
- }
- write_sfm(0,shi1);
- }
- }
- write_sfm(3,fen);
- }
- write_sfm(6,miao);
- }
- }
-
- void main()
- {
- TMOD=0x11;
- TH0=(65536-45872)/256;
- TL0=(65536-45872)%256;
- TH1=(65536-45872)/256;
- TL1=(65536-45872)%256;
- EA=1;
- ET0=1;
- TR0=1; //定时器0
- ET1=1;
- TR1=0; //定时器1,初始关闭运行
- EX0=1; //外部中断0中断允许位
- IT0=0; //外部中断0电平触发方式
- shi=19; //日历初值
- fen=29;
- miao=55;
- day=6;
- mon=11;
- year=2018;
- week=3;
- flag1=0; //小时为24制
- num4=0; //闹钟声为1号
- qie=0; //秒表开启时先为正走
- dula=0; //关闭段选
- wela=0; //关闭位选
- lcden=0; //使能端制0
- write_com(0x38);
- write_com(0x0c); //开显示,不显示光标
- write_com(0x06); //写一个地址之后,指针加一
- write_com(0x01); //显示清0,数据指针清0
- write_com(0x80); //第一个行显示
- {
- for(num=0;num<15;num++)
- {
- write_data(table[num]);
- delay(5);
- }
- write_com(0x80+0x40); //第一个行显示,左边显示数组
- for(num=0;num<13;num++)
- {
- write_data(table1[num]);
- delay(5);
- }
- }
- write_com(0x80+0x40+9); //第一个行显示,右边显示数组
- for(num=0;num<13;num++)
- {
- write_data(table2[num]);
- delay(5);
- }
- // zhuanhua();
- while(1)
- {
- jianpan();
- shixu();
- if(qie==0)
- {
- shixu1(); //秒表正走
- }
- if(qie==1)
- {
- shixu2(); //秒表倒走
- if(shi2==0&&fen1==0&&miao1==0)//如果走到0,那么定时器1 暂停k
- {
- TR1=0;
- }
- }
- }
- }
-
- void T0_time() interrupt 1 //定时器 中断服务程序k
- {
- TH0=(65536-45872)/256;
- TL0=(65536-45872)%256;
- a++;
- if((shi==19&&fen==30)&&(miao<3&&miao>=0)) //如果是在下午19点,30分,那么闹钟响铃3分钟k
- {
- if(num4==0) //闹钟铃声1,一直响k
- {
- {
- beep=0;
- }
- }
- if(num4==1) //闹钟铃声2,响一秒间断一秒再一秒k
- {
- if(miao==0)
- {
- beep=0;
- }
- if(miao==1)
- {
- beep=1;
- }
- if(miao==2)
- {
- beep=0;
- }
- }
- }
- if(shi==19&&fen==30&&miao==3)
- {
- beep=1;
- }
- }
- void T1_time() interrupt 3 //定时器1 中断服务程序k
- {
- TH1=(65536-45872)/256;
- TL1=(65536-45872)%256;
- a1++;
- }
-
- void INT0_0() interrupt 0 //外部中断默认中断级别最高A
- {
- // TR1=0;
- }
复制代码
所有资料51hei提供下载:
日历.docx
(19.08 KB, 下载次数: 11)
|