从左到右的开关控制分别为:秒设置、分设置、时设置、进入时间设置(设置时间需要按一下这个再按前面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; //蜂鸣器停 }
复制代码