设计要求:
使用AT89C51单片机设计一个简易的定时闹钟。
基本功能如下:
显示格式为“时时分分”。由分位闪动来做秒计数表示。
一旦时间到则发出声响。
程序执行后工作指示灯LED闪动,表示程序开始执行,显示器显示“0000”,按下操作键K1~K4动作如下:
(1) K1—设置现在的时间。
(2) K2—显示闹钟设置的时间。
(3) K3—设置闹铃的时间。
(4) K4—闹铃ON/OFF的状态设置,设置为ON时连续三次发出“哗”的一声,设置为OFF发出“哗”的一声。
设置当前时间或闹铃时间如下。
(1) K1—时调整。
(2) K2—分调整。
(3) K3—设置完成。
(4) K4—闹铃时间到时,发出一阵声响,按下本键可以停止声响。
求原理图,程序,和设计思想!!!
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
#define uchar unsigned char
#define uint unsigned int
sbit s1=P2^0; //数码管位选控制端
sbit s2=P2^1;
sbit s3=P2^2;
sbit s4=P2^3;
sbit s5=P2^4;
sbit s6=P2^5;
sbit s7=P2^6;
/*k1设置时间,k2定时。k1,k2使用不自动弹起按键。
k3时分秒选择,k4加数字,k5减数字。*/
sbit k1=P1^0;
sbit k2=P1^1;
sbit k3=P1^2;
sbit k4=P1^3;
sbit k5=P1^4;
uchar count=0,sec,min,hour,ss=0;s=60,m=60,h=24;
uchar code mum[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; //共阳数码管0-9编码
void delayms(uint k) //延时函数
{
uint i,j;
for(i=k;i>0;i--)
for(j=110;j>0;j--);
}
/*通过count获得hour,min,sec变量值 */
void timecontrol()
{
sec++;
if(sec==60)
{
sec=0;
min++;
if(min==60)
{
min=0;
hour++;
if(hour==24)
hour=0;
}
}
}
void display(uchar zs,uchar zm, uchar zh) //数码管显示函数
{
s1=1;
P0=mum[zh/10];
delayms(5);
s1=0;
s2=1;
P0=mum[zh%10]&0x7f; // 时的个位加上小数点
delayms(5);
s2=0;
s3=1;
P0=mum[zm/10];
delayms(5);
s3=0;
s4=1;
P0=mum[zm%10]&0x7f; //分的个位加上小数点
delayms(5);
s4=0;
s5=1;
P0=mum[zs/10];
delayms(5);
s5=0;
s6=1;
P0=mum[zs%10];
delayms(5);
s6=0;
}
void keyscan_settime() //时间设置模块
{
uchar st,mt,ht;
if(k1==0)
{
delayms(10);
if(k1==0)
{
st=sec,mt=min,ht=hour;
TR0=0; //关闭定时器
while(k1==0) //等待用户按键
{
display(st,mt,ht);
if(k3==0)
{
delayms(10);
if(k3==0)
{
while(!k3);
ss++;
if(ss==3) ss=0;
}
}
/*通过ss选择时分秒设置*/
if(k4==0) //加数
{
delayms(10);
if(k4==0)
{
while(!k4);
switch(ss)
{
case 0:st++;if(st==60)st=0;break;
case 1:mt++;if(mt==60)mt=0;break;
case 2:ht++;if(ht==24)ht=0;break;
default :;
}
}
}
if(k5==0) //减数
{
delayms(10);
if(k5==0)
{
while(!k5);
switch(ss)
{
case 0:if(st>0)st--;
else st=0;break;
case 1:if(mt>0)mt--;
else mt=0;break;
case 2:if(ht>0)ht--;
else ht=0;break;
default : ;
}
}
}
}
TR0=1;
sec=st,min=mt,hour=ht;
}
}
display(sec,min,hour);
}
void keyscan_time() //用户定时模块
{
if(k2==0)
{
delayms(10);
if(k2==0)
{
s=sec;m=min;h=hour;
while(k2==0) //开始定时设置
{
display(s,m,h);
if(k3==0)
{
delayms(10);
if(k3==0)
{
while(!k3);
ss++;
if(ss==3) ss=0;
}
}
/*通过ss选择时分秒设置*/
if(k4==0) //加数
{
delayms(10);
if(k4==0)
{
while(!k4);
switch(ss)
{
case 0:s++;if(s==60)s=0;break;
case 1:m++;if(m==60)m=0;break;
case 2:h++;if(h==24)h=0;break;
default :;
}
}
}
if(k5==0) //减数
{
delayms(10);
if(k5==0)
{
while(!k5);
switch(ss)
{
case 0:if(s>0)s--;
else s=0;break;
case 1:if(m>0)m--;
else m=0;break;
case 2:if(h>0)h--;
else h=0;break;
default : ;
} }
}
}
}
}
}
void buz()
{
if((hour==h)&&(min==m)&&(sec==s))
{
s7=0;
delayms(20);
s7=1;
}
}
void main()
{
TMOD=0x01; //定时器0工作在方式1
TH0=(65536-45872)/256; //装初值,50ms
TL0=(65536-45872)%256;
EA=1; //总中断允许
ET0=1; //T0中断允许
TR0=1; //开定时器0
while(1)
{
keyscan_settime();
keyscan_time();
buz();
}
}
void T0_ms() interrupt 1 //中断入口程序
{
TH0=(65536-45872)/256; //重新装初值
TL0=(65536-45872)%256;
count++;
if(count==20) //判定1s时间是否已到
{
count=0;
timecontrol();
}
你先自己调试一下,我这里试过是可以的。
一周热门 更多>