单片机入门之数码管定时闹钟(2)

控制/MCU

1878人已加入

描述

在之前的文章中我们学习了数码管定时闹钟中的按键中断的写法,接下来我们需要将我们的按键、蜂鸣器和我们之前设计的数码管计时器相结合起来,就可以实现一个数字时间现实的定时闹钟了。

一、功能概述

通过按键来控制设定的时间,当到达时间后进入外部中断,蜂鸣器开始工作,实现定时闹钟的功能。时间数字在四位数码管上进行显示,分钟倒计时定时闹钟的功能,在此基础上还可以添加小时的数码管,来对小时的时间进行设置,原理还是类似的。

二、显示原

本设计同样采用的AT89C51单片机来实现多位数码管的控制,附带按键设置时间,以及蜂鸣器闹钟的功能。

电路连接如下:

单片机

三、程序代码设计

结合我们前几章所学的数码管以及定时器、中断的方法来对程序进行编写。

程序如下:

#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;

}

四、总结

到这一章我们所学习的数码管应用也结束了,其实并没有想象中的复杂,数码管从一位到多位,段码并没有变化,而是用不同的位码来对每一个数码管进行控制,在之后我们还可以使用定时器的功能来实现对时间的计算,后来增加了外部中断,这使得时间可以由我们个人去通过按键来设定,在增加蜂鸣器就实现了数码管定时闹钟的设计目标。接下来我们将对SHT30温湿度传感器进行设计。

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分