简易数字钟仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
单片机源程序如下:
- #include<reg52.h>
- #define uchar unsigned char
- #define uint unsigned int
- sbit s1=P2^0; //数码管位选控制端
- sbit s2=P2^1;
- sbit s3=P2^2;
- sbit s4=P2^3;
- sbit s5=P2^4;
- sbit s6=P2^5;
- sbit s7=P2^6;
- /*k1设置时间,k2定时。k1,k2使用不自动弹起按键。
- k3时分秒选择,k4加数字,k5减数字。*/
- sbit k1=P1^0;
- sbit k2=P1^1;
- sbit k3=P1^2;
- sbit k4=P1^3;
- sbit k5=P1^4;
- uchar count=0,sec,min,hour,ss=0;s=60,m=60,h=24;
- uchar code mum[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; //共阳数码管0-9编码
- void delayms(uint k) //延时函数
- {
- uint i,j;
- for(i=k;i>0;i--)
- for(j=110;j>0;j--);
- }
- /*通过count获得hour,min,sec变量值 */
- void timecontrol()
- {
- sec++;
- if(sec==60)
- {
- sec=0;
- min++;
- if(min==60)
- {
- min=0;
- hour++;
- if(hour==24)
- hour=0;
- }
- }
- }
- void display(uchar zs,uchar zm, uchar zh) //数码管显示函数
- {
- s1=1;
- P0=mum[zh/10];
- delayms(5);
- s1=0;
-
- s2=1;
- P0=mum[zh%10]&0x7f; // 时的个位加上小数点
- delayms(5);
- s2=0;
-
- s3=1;
- P0=mum[zm/10];
- delayms(5);
- s3=0;
-
- s4=1;
- P0=mum[zm%10]&0x7f; //分的个位加上小数点
- delayms(5);
- s4=0;
-
- s5=1;
- P0=mum[zs/10];
- delayms(5);
- s5=0;
-
- s6=1;
- P0=mum[zs%10];
- delayms(5);
- s6=0;
- }
- void keyscan_settime() //时间设置模块
- {
- uchar st,mt,ht;
- if(k1==0)
- {
- delayms(10);
- if(k1==0)
- {
- st=sec,mt=min,ht=hour;
- TR0=0; //关闭定时器
- while(k1==0) //等待用户按键
- {
- display(st,mt,ht);
- if(k3==0)
- {
- delayms(10);
- if(k3==0)
- {
- while(!k3);
- ss++;
- if(ss==3) ss=0;
- }
- }
- /*通过ss选择时分秒设置*/
- if(k4==0) //加数
- {
- delayms(10);
- if(k4==0)
- {
- while(!k4);
- 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(k5==0) //减数
- {
- delayms(10);
- if(k5==0)
- {
- while(!k5);
- switch(ss)
- {
- case 0:if(st>0)st--;
- else st=0;break;
- case 1:if(mt>0)mt--;
- else mt=0;break;
- case 2:if(ht>0)ht--;
- else ht=0;break;
- default : ;
- }
- }
- }
- }
- TR0=1;
- sec=st,min=mt,hour=ht;
- }
- }
- display(sec,min,hour);
- }
- void keyscan_time() //用户定时模块
- {
- if(k2==0)
- {
- delayms(10);
- if(k2==0)
- {
- s=sec;m=min;h=hour;
- while(k2==0) //开始定时设置
- {
- display(s,m,h);
- if(k3==0)
- {
- delayms(10);
- if(k3==0)
- {
- while(!k3);
- ss++;
- if(ss==3) ss=0;
- }
- }
- /*通过ss选择时分秒设置*/
- if(k4==0) //加数
- {
- delayms(10);
- if(k4==0)
- {
- while(!k4);
- 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(k5==0) //减数
- {
- delayms(10);
- if(k5==0)
- {
- while(!k5);
- switch(ss)
- {
- case 0:if(s>0)s--;
- else s=0;break;
- case 1:if(m>0)m--;
- else m=0;break;
- case 2:if(h>0)h--;
- else h=0;break;
- default : ;
- } }
- }
- }
- }
- }
- }
- void buz()
- {
- if((hour==h)&&(min==m)&&(sec==s))
- {
- s7=0;
- delayms(40);
- s7=1;
- delayms(40);
- }
- }
- void zhengdian()
- {
- uchar i=0;
- if((sec==0)&(min==0))
- {
- for(i=0;i<10;i++)
- {
- TR0=1;
- buz();
- delayms(20);
- }
- }
- }
- void main()
- {
- TMOD=0x01; //定时器0工作在方式1
- TH0=(65536-45872)/256; //装初值,50ms
- TL0=(65536-45872)%256;
- EA=1; //总中断允许
- ET0=1; //T0中断允许
- TR0=1; //开定时器0
- while(1)
- {
- keyscan_settime();
- keyscan_time();
- buz();
- zhengdian();
- }
- }
- void T0_ms() interrupt 1 //中断入口程序
- {
- TH0=(65536-45872)/256; //重新装初值
- TL0=(65536-45872)%256;
- count++;
- if(count==20) //判定1s时间是否已到
- {
- count=0;
- timecontrol();
- }
- }
复制代码
所有资料51hei提供下载:
简易数字钟.rar
(126.3 KB, 下载次数: 87)
|