数拓做了一个数字钟,功能有年月日,时分秒,星期,闹钟,秒表,整点报时。通过按键切换不同功能。
材料简单,适合单片机新手
电路图
单片机源程序如下:
- #include<reg51.h>
- #define uchar unsigned char
- #define uint unsigned int
- /*****************************************
- 定义变量和数码表
- *******************************************/
- sbit s1=P0^0; //数码管位选控制端
- sbit s2=P0^1;
- sbit s3=P0^2;
- sbit s4=P0^3;
- sbit s5=P0^4;
- sbit s6=P0^5;
- sbit s7=P0^6; //LED闹钟
-
- sbit k1=P2^7; /*k1设置时间,k2定时。k1,k2使用不自动弹起按键。 k3时分秒选择,k4加数字,k5减数字。*/
- sbit k2=P2^6;
- sbit k3=P2^5;
- sbit k4=P2^4;
- uchar count=0,a=0,b=0,c=0,d=0,e=0,f=0,
- djss=0,djsm=0,djsh=0,st,mt,ht,sec,min,hour,w=0,ss=0,
- thousand,hundred,ten,ge,liang1,liang2;s=60,m=60,h=24;
- uint year=2017,month=5,day=12,week;
- uchar code mum[]={0xc0,0xf9,0xa4,0xb0,0x99,
- 0x92,0x82,0xf8,0x80,0x90}; //共阳数码管0-9编码
- void display(uchar zs,uchar zm, uchar zh);
- void WeekDay(uint y,uint M, uint d);
- unsigned mon(uchar mo);
- /*******************************************
- 延时程序
- 供动态扫描和按键去抖用
- *******************************************/
- void delayms(uint k) //延时函数
- {
- uint i,j;
- for(i=k;i>0;i--)
- for(j=110;j>0;j--);
- }
- /*******************************************
- 时间控制函数0
- *******************************************/
- void timecontrol() /*通过count获得hour,min,sec变量值 */
- {
- sec++;
- if(sec==60)
- {
- sec=0;
- min++;
- if(min==60)
- {
- min=0;
- hour++;
- if(hour==24)
- hour=0;
- }
- }
- }
- /*******************************************
- 时间控制函数1
- *******************************************/
- void timecontrol1()
- {
- djss++;
- if(djss==60)
- {
- djss=0;
- djsm++;
- if(djsm==60)
- {
- djsm=0;
- djsh++;
- if(djsh==24)
- djsh=0;
- }
- }
- }
- /*******************************************
- 整点报时程序
- *******************************************/
- void baoshi()
- {
- if((min=59)&(sec==59))/*整点报时功能*/
- {
- uchar bs;
- bs=sec;
- bs++;
- while(bs>0)/*报时次数等于小时数*/
- {
- bs--;
- s7=0;
- delayms(100);
- s7=1;
- delayms(100);
- }
- }
- }
- /*******************************************
- 数码管显示程序
- *******************************************/
- void display(uchar zs,uchar zm, uchar zh)
- {
- s1=1;
- P1=mum[zh/10];
- delayms(1);
- s1=0;
- s2=1;
- P1=mum[zh%10]&0x7f; // 时的个位加上小数点
- delayms(1);
- s2=0;
-
- s3=1;
- P1=mum[zm/10];
- delayms(1);
- s3=0;
-
- s4=1;
- P1=mum[zm%10]&0x7f; //分的个位加上小数点
- delayms(1);
- s4=0;
-
- s5=1;
- P1=mum[zs/10];
- delayms(1);
- s5=0;
-
- s6=1;
- P1=mum[zs%10];
- delayms(1);
- s6=0;
- }
- /*******************************************
- 按键选择程序
- *******************************************/
- void choose()
- {
- if(k2==0)
- {
- delayms(10);
- if(k2==0)
- {
- while(!k2);
- ss++;
- if(ss==3)
- ss=0;
- }
- }
- }
- void dm()
- {
- djss=0;
- djsm=0;
- djsh=0;
- TR1=0;
- while((w==5)&(k1==1))
- {
- display(djss,djsm,djsh);
- if(k2==0)
- {
- delayms(10);
- if(k2==0)
- {
- while(!k2);
- {
- TR1=1;display(djss,djsm,djsh);
- }
- }
- }
- if(k3==0)
- {
- delayms(10);
- if(k3==0)
- {
- while(!k3);
- TR1=0;
- }
- }
- if(k4==0)
- {
- delayms(10);
- if(k4==0)
- {
- while(!k4);
- {
- TR1=0;djss=0;djsm=0;djsh=0;
- }
- }
- }
- }
- }
- /*******************************************
- 时间设置函数
- *******************************************/
- void keyscan_settime()
- {
- display(sec,min,hour);
- if(k1==0)
- {
- delayms(10);
- if(k1==0) //关闭定时器
- {
- while(k1==0); //等待用户按键
- w++;
- }
- }
-
- }
- void tshi()
- {
- st=sec,mt=min,ht=hour;
- TR0=0; ss=0;
- while((w==1)&(k1==1))
- {
- display(st,mt,ht);
- choose(); /*通过ss选择时分秒设置*/
- if(k3==0) //加数
- {
- delayms(10);
- if(k3==0)
- {
- while(!k3);
- switch(ss)
- {
- case 0:st++;if(st==60)st=0;break;
- case 1:mt++;if(mt==60)mt=0;break;
- case 2:ht++;if(ht==24)ht=0;break;
- default : ;
- }
- }
- }
- if(k4==0) //减数
- {
- delayms(10);
- if(k4==0)
- {
- while(!k4);
- switch(ss)
- {
- case 0:if(st>0)st--;
- else st=59;break;
- case 1:if(mt>0)mt--;
- else mt=59;break;
- case 2:if(ht>0)ht--;
- else ht=23;break;
- default : ;
- }
- }
- }
- }
- }
- /*******************************************
- 定时函数
- *******************************************/
- void dshi()
- {
- TR0=1;
- sec=st,min=mt,hour=ht;
- s=sec;m=min;h=hour;ss=0;
- while((w==2)&(k1==1))
- {
- display(s,m,h);
- if(k2==0)
- {
- delayms(10);
- if(k2==0)
- {
- while(!k2);
- ss++;
- if(ss==3)
- ss=0;
- }
- } /*通过ss选择时分秒设置*/
- if(k3==0) //加数
- {
- delayms(10);
- if(k3==0)
- {
- while(!k3);
- switch(ss)
- {
- case 0:s++;if(s==60)s=0;break;
- case 1:m++;if(m==60)m=0;break;
- case 2:h++;if(h==24)h=0;break;
- default :;
- }
- }
- }
- if(k4==0) //减数
- {
- delayms(10);
- if(k4==0)
- {
- while(!k4);
- switch(ss)
- {
- case 0:if(s>0)s--;
- else s=59;break;
- case 1:if(m>0)m--;
- else m=59;break;
- case 2:if(h>0)h--;
- else h=23;break;
- default : ;
- }
- }
- }
- }
- }
- /*******************************************
- 年调整程序
- *******************************************/
- void year_change()
- {
- ss=1;
- while((w==3)&(k1==1))
- {
- display(0,liang1,liang2);
- if(k2==0)
- {
- delayms(10);
- if(k2==0)
- {
- while(!k2);
- ss++;
- if(ss==3)
- ss=1;
- }
- } /*通过ss选择时分秒设置*/
- if(k3==0) //加数
- {
- delayms(10);
- if(k3==0)
- {
- while(!k3);
- switch(ss)
- {
- case 1:liang1++;if(liang1==100)liang1=0;break;
- case 2:liang2++;if(liang2==21)liang2=0;break;
- default :;
- }
- }
- }
- if(k4==0) //减数
- {
- delayms(10);
- if(k4==0)
- {
- while(!k4);
- switch(ss)
- {
- case 1:if(liang1>0)liang1--;
- else liang1=99;break;
- case 2:if(liang2>0)liang2--;
- else liang2=20;break;
- default : ;
- }
- }
- }
- }
- }
- /*******************************************
- 月日调整程序
- *******************************************/
- void md_change()
- {
- ge=liang1%10;
- ten=liang1%100/10;
- hundred=liang2%10;
- thousand=liang2%100/10;
- year=thousand*1000+hundred*100+ten*10+ge;
- ss=1;
- while((w==4)&(k1==1))
- {
- WeekDay(year,month,day);
- display(week,day,month);
- if(k2==0)
- {
- delayms(10);
- if(k2==0)
- {
- while(!k2);
- ss++;
- if(ss==3)
- ss=1;
- }
- } /*通过ss选择时分秒设置*/
- if(k3==0) //加数
- {
- delayms(10);
- if(k3==0)
- {
- while(!k3);
- switch(ss)
- {
- case 1:day++;
- if(day==(mon(month)+1))day=1;
- break;
- case 2:month++;if(month==13)month=1;
- break;
- default :;
- }
- }
- }
- if(k4==0) //减数
- {
- delayms(10);
- if(k4==0)
- {
- while(!k4);
- switch(ss)
- {
- case 1:if(day>1)day--;
- else day=mon(month);break;
- case 2:if(month>1)month--;
- else month=12;break;
- default : ;
- }
- }
- }
- }
- }
- /*******************************************
- 时分秒调整程序
- *******************************************/
- void buz()
- {
- if((hour==h)&&(min==m)&&(sec==s))
- {
- TR1=1;b=0;
- while(1)
- {
- if(b%2==0)
- {
- s7=0;
- display(sec,min,hour);
- }
- else{ s7=1;
- display(sec,min,hour);}
- if(b==11)
- {
- s7=1;b=0;TR1=0;break;
- }
- if(k4==0) //减数
- {
- delayms(10);
- if(k4==0)
- {
- while(!k4);
- {s7=1;break;
- }
- }
- }
- }
- }
- }
- /*******************************************
- 闰年判断程序
- *******************************************/
- unsigned leap(uchar y) //判断是否闰年并返回二月份的天数
- { //闰年返回29,平年返回28
- y+=2000;
- if(y%4==0)
- {
- if(y%100==0)
- {
- if(y%400==0)
- return 29;
- else
- return 28;
- }
- else
- return 29;
- }
- else
- return 28;
- }
- /*******************************************
- 月返回函数
- *******************************************/
- unsigned mon(uchar mo) //计算并返回每个月的天数
- {
- switch(mo)
- {
- case 1:
- case 3:
- case 5:
- case 7:
- case 8:
- case 10:
- case 12: return 31;
- break; //1,3,5,7,8,10,12月每月31天
- case 4:
- case 6:
- case 9:
- case 11: return 30;
- break; //4,6,9,11月每月30天
- case 2: return leap(year);
- break; //返回二月份的天数
- default: break;
- }
- }
- /*******************************************
- 星期显示程序
- *******************************************/
- void WeekDay(uint y,uint M, uint d)
- {
- if(M==1||M==2)
- {
- M+=12;
- y--;
- }
- week=(d+2*M+3*(M+1)/5+y+y/4-y/100+y/400+1)%7;
- if(week==0)
- week=7;
- }
- void ymd()
- {
- if(w==0)
- {
- if(k3==0)
- {
- delayms(10);
- if(k3==0)
- {
- while(!k3);
- c++;
- }
- }
- }
- }
- void ymd1()
- {
- display(0,liang1,liang2);
- }
- void ymd2()
- {
- WeekDay(year,month,day);
- display(week,day,month);
- }
- /*******************************************
- 主函数程序
- *******************************************/
- void main()
- {
- TMOD=0x11; //定时器0工作在方式1
- TH0=(65536-45872)/256; //装初值,50ms
- TL0=(65536-45872)%256;
- EA=1; //总中断允许
- ……………………
- …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
所有资料51hei提供下载:
数拓---数字钟设计.rar
(137.66 KB, 下载次数: 112)
|