时钟可以显示到秒位
从左到右的开关控制分别为:秒设置、分设置、时设置、进入时间设置(设置时间需要按一下这个再按前面3个按键设置)、闹钟设置(通过前面3个按键设置)、保存设置(设置完成后按下保存并退出)。
数码管用的是共阴,共阳的话加三极管闲麻烦,没加。
数码管a~g接的P0口,没用10K排阻上拉,试了下觉得亮度太低了,就都换成了2K的作为上拉。
有兴趣的可以给加上温度传感器,可以显示温度(我这里面就没加了)
初学单片机没多久,欢迎大佬指导。
材料如下:89C52*1
4位数码管*1+2位数码管*1(当然如果有六位的也可以直接用,找不到其他数码管了就这么混搭了)
有源蜂鸣器*1(试过无源,但时间计算过于占用资源导致发声不是很完美,大佬可以改一下)
轻触开关*7(1个用于复位,其余六个用于设置) + 自锁开关*1
电池*1 + 5V稳压*1
单片机源码:
- #include <reg52.h>
- #define uint unsigned int
- #define uchar unsigned char
- sbit WE1=P2^5;
- sbit WE2=P2^4;
- sbit WE3=P2^3;
- sbit WE4=P2^2;
- sbit WE5=P2^1;
- sbit WE6=P2^0;
- sbit K1=P1^0; //设置小时位
- sbit K2=P1^1; //设置分位
- sbit K3=P1^2; //设置秒位
- sbit K4=P1^3; //进入时间设置
- sbit K5=P1^4; //进入闹钟设置
- sbit K6=P1^5; //退出设置
- sbit BZ=P1^6; //蜂鸣器接口
- uchar code table[]={
- 0XC0,0XF9,0XA4,
- 0XB0,0X99,0X92,
- 0X82,0XF8,0X80,
- 0X90};
- uint tt=0,i=0,j=0,T=0,R=0,S;
- uint W1=0,W2=0,W3=0,W4=0,W5=0,W6=0; //当前时间位,依次接P0口即可,即W1=P0^0,W2=P0^2.....以此类推
- uint WD1=0,WD2=0,WD3=0,WD4=0,WD5=0,WD6=0; //闹钟时间位,用于储存设置的闹钟时间,不接
- void delay(uint); //软延时
- //void delay1(uint);
- void js(void); //时钟进位定义
- void key(void); //按键
- void XS(uint,uint,uint,uint,uint,uint); //动态扫描数码管显示
- void xhsz(uint,uint,uint,uint,uint,uint,uint); //时钟位设置函数
- void main()
- {
- P1=0X0;
- TMOD=0X01;
- TH0=(65536-49971)/256;
- TL0=(65536-49971)%256;
- //TH1=(65536-65535)/256; //定时器二(未启用)
- //TL1=(65536-65535)%256;
- EA=1;
- ET0=1;
- //ET1=1;
- TR0=1;
- //TR1=1;
- while(1)
- {
- key();
- XS(W1,W2,W3,W4,W5,W6);
- js();
- if(WD1==W1&&WD2==W2&&WD3==W3&&WD4==W4&&WD5==W5&&WD6==W6) //闹钟定时判断
- T=1;
- }
- }
- void xhsz(uint Q1,uint Q2,uint Q3,uint Q4,uint Q5,uint Q6,uint Y) //输入需要设置的位Q1~Q6,末尾输入1则将值赋给W1~W6,输入0则赋给WD1~WD6
- {
- while(1)
- {
- if(Y==1)
- {
- W1=Q1;W2=Q2;W3=Q3;W4=Q4;W5=Q5;W6=Q6;
- }
- if(Y==0)
- {
- WD1=Q1;WD2=Q2;WD3=Q3;WD4=Q4;WD5=Q5;WD6=Q6;
- }
- if(K1==1)//秒调
- {
- delay(10);
- if(K1==1)
- {
- while(K1==1)
- XS(Q1,Q2,Q3,Q4,Q5,Q6);
- Q1++;
- if(Q1>9)
- {Q2++;Q1=0;}
- if(Q2>5)
- {Q2=0;Q3=0;}
- }
- }
- if(K2==1)//分调
- {
- delay(10);
- if(K2==1)
- {
- while(K2==1)
- XS(Q1,Q2,Q3,Q4,Q5,Q6);
- Q3++;
- if(Q3>9)
- {Q4++;Q3=0;}
- if(Q4>5)
- {Q4=0;Q3=0;}
- }
- }
- if(K3==1)//时调
- {
- delay(10);
- if(K3==1)
- {
- while(K3==1)
- XS(Q1,Q2,Q3,Q4,Q5,Q6);
- Q5++;
- if(Q5>9)
- {Q6++;Q5=0;}
- if(Q5>3&&Q6>1)
- {Q6=0;Q5=0;}
- }
- }
- XS(Q1,Q2,Q3,Q4,Q5,Q6);
- if(K6==1)
- break;
- }
- }
- void key()
- {
- if(K4==1) //设置时间
- {
- delay(10);
- if(K4==1)
- {
- while(K4==1);
- TR0=0;
- xhsz(W1,W2,W3,W4,W5,W6,1);
- TR0=1;
- }
- }
-
- if(K5==1) //设置闹钟
- {
- delay(10);
- if(K5==1)
- {
- while(K5==1);
- xhsz(WD1,WD2,WD3,WD4,WD5,WD6,0);
- }
- }
- if(K6==1) //关闭闹钟
- {
- delay(10);
- if(K6==1)
- {
- while(K6==1);
- T=0;
- BZ=0;
- }
- }
- }
- void time() interrupt 1 //定时器1
- {
- TH0=(65536-49971)/256;
- TL0=(65536-49971)%256;
- tt++;
- js();
- if(T==1)
- {
- R++;
- if(R==1000) //闹钟响铃时间 计算方式是R*50ms,这里设置的是50S
- {T=0;R=0;}
- }
- }
- /*void time1() interrupt 3
- {
- TH1=(65536-65535)/256;
- TL1=(65536-65535)%256;
- S++;
- }*/
- void delay(uint t)
- {
- for(i=t;i>0;i--)
- {
- for(j=90;j>0;j--);
- }
- }
- /*void delay1(uint S)
- {
- for(i=S;i>0;i--)
- {
- for(j=1;j>0;j--);
- }
- }*/
- void js()
- {
- if(tt==20)
- {
- tt=0;
- W1++;
- }
-
- if(W1>9)
- {
- W2++;
- W1=0;
- }
-
- if(W2>5)
- {
- W3++;
- W2=0;
- }
-
- if(W3>9)
- {
- W4++;
- W3=0;
- }
-
- if(W4>5)
- {
- W5++;
- W4=0;
- }
-
- if(W5>9)
- {
- W6++;
- W5=0;
- }
-
- if(W5>3&&W6>1)
- {
- W1=0;
- W2=0;
- W3=0;
- W4=0;
- W5=0;
- W6=0;
- }
- }
- void XS(uint Q1,uint Q2,uint Q3,uint Q4,uint Q5,uint Q6)
- {
- WE1=0;
- P0=~table[Q1];
- delay(3);
- WE1=1;
-
- WE2=0;
- P0=~table[Q2];
- delay(3);
- WE2=1;
-
- WE3=0;
- P0=~table[Q3];
- delay(3);
- WE3=1;
-
- WE4=0;
- P0=~table[Q4];
- delay(3);
- WE4=1;
-
- WE5=0;
- P0=~table[Q5];
- delay(3);
- WE5=1;
-
- WE6=0;
- P0=~table[Q6];
- delay(3);
- WE6=1;
-
- if(T==1)
- BZ=1; //蜂鸣器响
- if(T==0)
- BZ=0; //蜂鸣器停
- }
复制代码
附上电路+程序:
数码管时钟.rar
(46.54 KB, 下载次数: 374)
|