之前做了一个单片机课设,用51单片机实现时钟闹钟,程序比较简单,思路也有很多种,放上我的代码供大家参考。
按键功能说明:
矩阵键盘:
第1到第10个按键分别对应数字0-9;
独立按键:
Key1短按切换模式,长按时钟暂停;
Key2按下则进行时钟和闹钟的设置;
Key3短按确认输入时间,长按清零。
(开发板上Key4故障,大家也可以把长按或短按功能设为Key4)
#include<reg52.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit key1=P3^0;//按键
sbit key2=P3^1;
sbit key3=P3^2;
sbit key4=P3^3;
sbit buffer=P2^3;//蜂鸣器
sbit DU =P2^6;//段选
sbit WE =P2^7;//位选
uchar bitdata[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//数码管1-8
uchar segdata[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40};//段选0-9,-
uchar dis_arr[]={10,10,10,10,10,10};//时钟显示数组
uchar time[]={0,0,0};//时钟 时分秒
uchar time_In[]={0,0,0,0,0,0};
uchar time_clk[]={0,0,0};//闹钟 时分秒
uchar num=0;
uchar mode=0;
uchar keydown=0;
uchar clk_state=0;
uchar keyIn,keyvalue,i,temp;//矩阵键盘读入
void key();
void init();
uchar keyscan();//矩阵键盘扫描函数
void delayms(uint x);//延时函数
void display(uchar duan1,uchar duan2,uchar duan3,uchar duan4,uchar duan5,uchar duan6);
void display_1(uchar wei,uchar duan);
void input();
void soundTime();
void main()
{
input();
init();
while(1)
{
key();
if(mode==0)//时钟
display(time[0]/10,time[0]%10,time[1]/10,time[1]%10,time[2]/10,time[2]%10);
else if(mode==1)//闹钟
display(time_clk[0]/10,time_clk[0]%10,time_clk[1]/10,time_clk[1]%10,time_clk[2]/10,time_clk[2]%10);
}
}
void init()//初始化函数
{
P3=0xff;//给高电平
TMOD=0x01;//定时器工作方式选择1
TH0=(65536-45872)/256;
TL0=(65536-45872)%256;
EA=1; //开总中断
ET0=1;//允许定时器0中断
TR0=1;//开始计数
//P1=1;
}
void delayms(uint x)//延时函数
{
uint i,j;
for(i=x;i>0;i--)
for(j=110;j>0;j--);
}
void key()
{
while(key2==0)
{
input();
break;
}
if(key1==0)
{
delayms(200);
if(key1==0)
//{while(!key1){TR0=0;display(time[0]/10,time[0]%10,time[1]/10,time[1]%10,time[2]/10,time[2]%10);}TR0=1;}
{TR0=!TR0;while(!key1)display(time[0]/10,time[0]%10,time[1]/10,time[1]%10,time[2]/10,time[2]%10);}
//else if(TR0==0)TR0=1;}
else if(key1==1)
{mode++;if(mode==2)mode=0;}
}
if(key3==0)
{
delayms(200);
if(key3==0)
{if(mode==0){time[0]=0;time[1]=0;time[2]=0;num=0;
while(!key3)display(time[0]/10,time[0]%10,time[1]/10,time[1]%10,time[2]/10,time[2]%10);}
else if(mode==1){time_clk[0]=0;time_clk[1]=0;time_clk[2]=0;
while(!key3)display(time_clk[0]/10,time_clk[0]%10,time_clk[1]/10,time_clk[1]%10,time_clk[2]/10,time_clk[2]%10);}}
else if(key3==1)
{buffer=1;/*P1=1;*/}
}
}
uchar keyscan()//矩阵键盘扫描函数
{
keyvalue=99;
P3=0xfe;
temp=P3;
temp=temp&0xf0;//判断是否还等于0xf0
while(temp!=0xf0)
{
delayms(5);
temp=P3;
temp=temp&0xf0;
while(temp!=0xf0)
{
temp=P3;
switch(temp)
{
case 0xee:{keyvalue=0;keydown=1;break;}
case 0xde:{keyvalue=1;keydown=1;break;}
case 0xbe:{keyvalue=2;keydown=1;break;}
case 0x7e:{keyvalue=3;keydown=1;break;}
}
while(temp!=0xf0)
{
temp=P3;
temp=temp&0xf0;
}
}
}
P3=0xfd;
temp=P3;
temp=temp&0xf0;//判断是否还等于0xf0
while(temp!=0xf0)
{
delayms(5);
temp=P3;
temp=temp&0xf0;
while(temp!=0xf0)
{
temp=P3;
switch(temp)
{
case 0xed:{keyvalue=4;keydown=1;break;}
case 0xdd:{keyvalue=5;keydown=1;break;}
case 0xbd:{keyvalue=6;keydown=1;break;}
case 0x7d:{keyvalue=7;keydown=1;break;}
}
while(temp!=0xf0)
{
temp=P3;
temp=temp&0xf0;
}
}
}
P3=0xfb;
temp=P3;
temp=temp&0xf0;//判断是否还等于0xf0
while(temp!=0xf0)
{
delayms(5);
temp=P3;
temp=temp&0xf0;
while(temp!=0xf0)
{
temp=P3;
switch(temp)
{
case 0xeb:{keyvalue=8;keydown=1;break;}
case 0xdb:{keyvalue=9;keydown=1;break;}
case 0xbb:{keyvalue=10;keydown=1;break;}
case 0x7b:{keyvalue=11;keydown=1;break;}
}
while(temp!=0xf0)
{
temp=P3;
temp=temp&0xf0;
}
}
}
P3=0xf7;
temp=P3;
temp=temp&0xf0;//判断是否还等于0xf0
while(temp!=0xf0)
{
delayms(5);
temp=P3;
temp=temp&0xf0;
while(temp!=0xf0)
{
temp=P3;
switch(temp)
{
case 0xe7:{keyvalue=12;keydown=1;break;}
case 0xd7:{keyvalue=13;keydown=1;break;}
case 0xb7:{keyvalue=14;keydown=1;break;}
case 0x77:{keyvalue=15;keydown=1;break;}
}
while(temp!=0xf0)
{
temp=P3;
temp=temp&0xf0;
}
}
}
return keyvalue;
}
void display(uchar duan1,uchar duan2,uchar duan3,uchar duan4,uchar duan5,uchar duan6)
{
display_1(0,duan1);
delayms(1);
display_1(1,duan2);
delayms(1);
display_1(2,10);
delayms(1);
display_1(3,duan3);
delayms(1);
display_1(4,duan4);
delayms(1);
display_1(5,10);
delayms(1);
display_1(6,duan5);
delayms(1);
display_1(7,duan6);
delayms(1);
}
void display_1(uchar wei,uchar duan)
{
DU=1;
P0=segdata[duan];
DU=0;
P0=0xff;
WE=1;
P0=bitdata[wei];
WE=0;
P0=0x00;
}
void input()//输入
{
EA=0;
for(i=0;i<8;i++)//重置为-便于下次使用
dis_arr[i]=10;
while(1)
{
display(dis_arr[0],dis_arr[1],dis_arr[2],dis_arr[3],dis_arr[4],dis_arr[5]);
keyIn=keyscan();
if(keydown==1)
{
keydown=0;
dis_arr[0]=keyIn;
time_In[0]=keyIn;
if(time_In[0]>=0&&time_In[0]<=2)
break;
}
}
while(1)
{
display(dis_arr[0],dis_arr[1],dis_arr[2],dis_arr[3],dis_arr[4],dis_arr[5]);
keyIn=keyscan();
if(keydown==1)
{
keydown=0;
dis_arr[1]=keyIn;
time_In[1]=keyIn;
if((time_In[1]>=0&&time_In[1]<=9)&&(time_In[0]*10+time_In[1])<24)
break;
}
}
while(1)
{
display(dis_arr[0],dis_arr[1],dis_arr[2],dis_arr[3],dis_arr[4],dis_arr[5]);
keyIn=keyscan();
if(keydown==1)
{
keydown=0;
dis_arr[2]=keyIn;
time_In[2]=keyIn;
if(time_In[2]>=0&&time_In[2]<=5)
break;
}
}
while(1)
{
display(dis_arr[0],dis_arr[1],dis_arr[2],dis_arr[3],dis_arr[4],dis_arr[5]);
keyIn=keyscan();
if(keydown==1)
{
keydown=0;
dis_arr[3]=keyIn;
time_In[3]=keyIn;
if((time_In[3]>=0&&time_In[3]<=9)&&(time_In[2]*10+time_In[3])<60)
break;
}
}
while(1)
{
display(dis_arr[0],dis_arr[1],dis_arr[2],dis_arr[3],dis_arr[4],dis_arr[5]);
keyIn=keyscan();
if(keydown==1)
{
keydown=0;
dis_arr[4]=keyIn;
time_In[4]=keyIn;
if(time_In[4]>=0&&time_In[4]<=5)
break;
}
}
while(1)
{
display(dis_arr[0],dis_arr[1],dis_arr[2],dis_arr[3],dis_arr[4],dis_arr[5]);
keyIn=keyscan();
if(keydown==1)
{
keydown=0;
dis_arr[5]=keyIn;
time_In[5]=keyIn;
if((time_In[5]>=0&&time_In[5]<=9)&&(time_In[4]*10+time_In[5])<60)
{
if(mode==0)
{time[0]=time_In[0]*10+time_In[1];
time[1]=time_In[2]*10+time_In[3];
time[2]=time_In[4]*10+time_In[5];}
else if(mode==1)
{time_clk[0]=time_In[0]*10+time_In[1];
time_clk[1]=time_In[2]*10+time_In[3];
time_clk[2]=time_In[4]*10+time_In[5];}
break;
}
}
}
while(1)
{
display(dis_arr[0],dis_arr[1],dis_arr[2],dis_arr[3],dis_arr[4],dis_arr[5]);
if(key3==0)
{
delayms(10);
if(key3==0)
{
EA=1;
break;}
}
}
}
void T0_time() interrupt 1//中断函数
{
TH0=(65536-45872)/256;
TL0=(65536-45872)%256;
num++;
if(num==20)//循环20次为一秒
{
num=0;
time[2]++;//秒加一
if(time[2]==60)//秒到60进位
{
time[2]=0;//秒清零分钟加一
time[1]++;
if(time[1]==60)//分钟到60进位
{
time[1]=0;//分钟清零小时加一
time[0]++;
soundTime();//整点报时
if(time[0]==24)//小时满24清零
time[0]=0;
}
}
if((time[0]==time_clk[0])&&(time[1]==time_clk[1])&&(time[2]==time_clk[2]))
{buffer=0;/*P1=0;*/}
}
}
void soundTime()
{
buffer=0;
delayms(10);
buffer=1;
}