原理图用PROTEL99SE画的,整点报时(倒数几秒蜂鸣器响),4位数码管显示时和分,两个发光二极管闪烁代表秒信号。详细的程序清单和流程图。
程序流程图:
单片机源程序如下:
- #include<reg52.h>
- #define uchar unsigned char
- #define uint unsigned int
- void delay();
- uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,
- 0x07,0x7f,0x6f,0x00,0x7c,0x39,0x5e,
- 0x79,0x71};//共阴数码管代码
- uint x,y,q,b,s,g,cunshi,cunfen,t0;
- uchar sigh,sigh2=1,sigh3,banmiao,miaozt,nz;//banmiao是半秒标志位,miaozt是让调时时小数点不闪
- uint nshi,nfen;//闹钟时、分变量
- int bxshi,bsshi;//报时时间段变量,上下限
- int miao,fen,shi;
- uchar count1,count2,count3,count4,count5;
- sbit K1=P1^0;//位选0到3
- sbit K2=P1^1;
- sbit K3=P1^2;
- sbit K4=P1^3;
- sbit deep=P2^0;
- sbit an1=P0^0;
- sbit an2=P0^1;
- sbit an3=P0^2;
- sbit an4=P0^3;
- sbit hong=P2^2;
- void init();
- void display(int q,int b,int s,int g);
- void ajcl();//按键及处理
- void baoshiyf();//报时与否函数
- void kaiji();//开机系统检测
- void nzzx();//闹钟执行
- void main()
- {
- init();
- while(1)
- {
- kaiji();
- ajcl();
- display(q,b,s,g);
- baoshiyf();
- nzzx();
- }
- }
- void init()
- {
- hong=1;
- P3=0xc0;
- K1=0;K2=0;K3=0;K4=0;
- P3=0xc0;
- K1=1;K2=1;K3=1;K4=1;
- TMOD=0x11;ET1=1;x=65000;
- TH0=(65536-50000)/256;
- TL0=(65536-50000)%256;
- TH1=65000/256;
- TL1=65000%256;
- EA=1;
- ET0=1;
- TR0=1;
- deep=0;
- nz=1;
- bxshi=6;bsshi=22;
- }
- void ajcl() //按键及处理
- {
-
-
- if(an1==0) { y=200; while(y--); if(an1==0) count1++;
- while(!an1) {display(q,b,s,g);} } //1键按键计数
-
- if(an2==0) { y=200; while(y--); if(an2==0) count2++;
- while(!an2) {display(q,b,s,g);} } //2键按键计数
-
- if(count4==0)
- {
- if(an3==0) { y=200; while(y--); if(an3==0) count3++;
- while(!an3) {display(q,b,s,g);} } //3键按键计数
- }
- if(count3==0 || count3==3)
- {
- count3=0;
- if(an4==0) { y=200; while(y--); if(an4==0) count4++;
- while(!an4) {display(q,b,s,g);}} //4键按键计数
- }
-
- P0=0xff;
- q=cunshi/10; b=cunshi%10; s=cunfen/10; g=cunfen%10;
- ////////////////////////////////////////接下来按an4触发可调时间
- if (count4 && !count3)
- {
- cunshi = shi; cunfen = fen;
- miaozt=1;
- switch(count4)
- {
- case 1 : if((shi==0)&&count2) shi=24 ;
- shi = shi+count1; count1=0;
- shi = shi-count2; count2=0;
- if(shi==24) shi=0;
- if (banmiao) {q=10; b=10; }
- else {q=shi/10; b=shi%10;} break;
- case 2 : if((fen==0)&&count2) fen=60;
- fen = fen+count1; count1=0;
- fen = fen-count2; count2=0;
- if(fen==60) fen=0;
- if (banmiao) {s=10; g=10; }
- else {s=fen/10; g=fen%10;} break;
- case 3 : miao=0;count4=0; break;
- }
- }
- ////////////////////////////////////////接下来按an3触发可定闹钟和报时时间段
- if (count3 && (!count4))
- {
- cunshi = nshi; cunfen = nfen;
- miaozt=1;
-
- switch(count3)
- {
- case 1 : s=nfen/10; g=nfen%10;
- if((nshi==0)&&count2) nshi=24;
- nshi = nshi+count1; count1=0;
- nshi = nshi-count2; count2=0;
- if(nshi==24) nshi=0;
- if (banmiao) {q=10; b=10; }
- else {q=nshi/10; b=nshi%10;} break;
-
- case 2 : q=nshi/10; b=nshi%10;
- if((nfen==0)&&count2) nfen=60;
- nfen = nfen+count1; count1=0;
- nfen = nfen-count2; count2=0;
- if(nfen==60) nfen=0;
- if (banmiao) {s=10; g=10; }
- else {s=nfen/10; g=nfen%10;} break;
-
- case 3 : cunshi=shi; cunfen=fen; break;
-
- case 4 : cunshi = bxshi; cunfen = bsshi;
- s=bsshi/10; g=bsshi%10;
- if((bxshi==0)&&count2) bxshi=24;
- bxshi = bxshi+count1; count1=0;
- bxshi = bxshi-count2; count2=0;
- if(bxshi==24) bxshi=0;
- if (banmiao) {q=10; b=10; }
- else {q=bxshi/10; b=bxshi%10;} break;
-
- case 5 : cunshi = bxshi; cunfen = bsshi;
- q=bxshi/10; b=bxshi%10;
- if((bsshi==0)&&count2) bsshi=24;
- bsshi = bsshi+count1; count1=0;
- bsshi = bsshi-count2; count2=0;
- if(bsshi==24) bsshi=0;
- if (banmiao) {s=10; g=10; }
- else {s=bsshi/10; g=bsshi%10;} break;
- case 6 : count3=0; cunshi=shi; cunfen=fen; break;
- }
- }
-
- ///////////////////////////////////////////时分 秒切换
- if(count1 && (!count3) && (!count4) )
- {
- if(count1==1)
- { q=10; b=10; s=miao/10; g=miao%10; miaozt=1; }
- else count1=0 ;
- }
-
- }
- void timer0() interrupt 1
- {
- t0++;
- TH0=(65536-50000)/256;
- TL0=(65536-50000)%256;
-
- if(t0==10) {banmiao=1;miaozt=1;}
- if(t0==20) {banmiao=0;miaozt=0;t0=0;miao++;sigh=1;}
- if(miao==11) {sigh2=0; }
- if(miao==60) {miao=0;fen++;sigh3=1;}
- if(fen==60) {fen=0;shi++; }
- if(shi==24) {shi=0; }
- cunshi=shi; cunfen=fen;
- }
- void timer1() interrupt 3
- {
- TH1=x/256;
- TL1=x%256;
- deep=~deep;
- }
- void display(int q,int b,int s,int g)
- {
- P3=~table[g];
- K4=0; delay();
- K4=1;
- P3=~table[s];
- K3=0; delay();
- K3=1;
- P3=t0<9?(P3=~(table[b]+0x80)):(P3=~table[b]);
- K2=0; delay();
- K2=1;
- P3=~table[q];
- K1=0; delay();
- K1=1;
- }
- void baoshiyf()
- {
- if( ((shi+1) >= bxshi) && (shi < bsshi) )
- {
- if( fen==59 )
- {
- if(( (miao==56) || (miao==57) || (miao==58) || (miao==59) )&&(t0<8))
- {x=65000;nz=0;TR1=1;}
- if(( (miao==56) || (miao==57) || (miao==58) || (miao==59) )&&(t0>7)) TR1=0;nz=1;
- }
- if( sigh &&(fen==0) && (miao==0) && (t0<14) )
- {
- x=65150;
- nz=0;TR1=1;
- }
- if( sigh&& (fen==0) && (miao==0) && (t0==14) )
- TR1=0;nz=1;
- }
- if(shi==bsshi)
- {
- if(sigh &&(fen==0) && (miao==0) && (t0<14) )
- { x=65150; nz=0;TR1=1;}
- if( sigh&& (fen==0) && (miao==0) && (t0==14) ) TR1=0;nz=1;
- }
- }
- void kaiji()
- {
- if(sigh2)
- {
- if( (miao!=0) && (t0<5) )
- {x=64800;nz=0;TR1=1;}
- if( (miao!=0) && (t0>4) )
- TR1=0;nz=1;
- if (t0<13) hong=1;
- else hong=0;
- }
- }
- void delay()
- {
- uint x,y;
- for(x=50;x>0;x--)
- for(y=1;y>0;y--);
- }
- void nzzx()
- { if(sigh3)
- {
- if((nshi==shi)&&(nfen==fen)&&(miao<31))
- { x=65300; TR1=1; }
- else
- if(nz)
- { TR1=0; }
- }
- }
复制代码
所有资料51hei提供下载:
电子钟原理图及程序(4位共阳数码管).rar
(114.33 KB, 下载次数: 109)
|