多功能电子钟程序完全好使.docx
《多功能电子钟程序完全好使.docx》由会员分享,可在线阅读,更多相关《多功能电子钟程序完全好使.docx(22页珍藏版)》请在冰豆网上搜索。
多功能电子钟程序完全好使
/*设计功能:
1.时钟功能(上排数码管)
每秒更新一次时钟显示,显示方式为MM.SS,其中M为分钟,S为秒。
可以通过按键调整当前时间,调整时间时需要闪烁调整位置的数值。
2.秒表功能(下排数码管)
按开始按键开始走秒,按停止按键停止走秒,按清除按键秒表归零,显示方式为:
SSS.U,其中S为秒,U为0.1秒。
3.闹钟功能(下排数码管)
用按键设置闹钟时间,显示格式为MM.SS。
闹钟时间到达后,闪烁一个指示灯。
可以用按键设置闹钟、取消闹钟。
各个按键功能可以自行定义,每按一次任何按键,D2灯会翻转一次状态
*/
/*
硬件连接:
一个有上下两个4位共阳数码管,4个按键,2个LED指示灯
P2高四位控制上排数码管位选,低4位控制下排数码管位选,P0控制段选
四个按键为独立按键,与P2高4位相连,与数码管复用
LED0接P34,LED1接P35
*/
/*
使用方法:
第一步:
设定系统时间,在上排的4位数码管显示,注意系统时间设定确认后就不得修改了
第二步:
选择秒表模式或闹钟模式,在下排的4位数码管显示。
两种模式只能选择一种,并且不能切换。
1.设定系统时间
此时按键定义:
S5移位,S6加,S7减,S8确认
一开始上电时数字全0不闪烁,默认从第一位开始设置,按下加减进行调节,如此要更换调节位置,每按一次S5会右移一位,移到第四位再按会重新移回第一位。
设置完系统时间,按下S8确认,跳出设定环节,进入秒表和闹钟模式选择环节。
2。
秒表和闹钟模式选择
此时按键定义:
S5改变模式标志,S6S7未用,S8确认进入该模式
设置完系统时间,进入秒表和闹钟模式选择环节。
此时第一位为0。
然后按S5,第一位会在1和2之间来回切换,在显示1时按S8进入秒表模式,在显示2时按S8进入闹钟模式,
2.1秒表模式
此时按键定义:
S5未用,S6开始,S7停止,S8清除
2.2闹钟模式
此时按键定义:
S5移位,S6加,S7减,S8按一次确认,等报警到了,再按S8停止报警
如设定系统时间的步骤,设定好闹钟时间,按S8确认设定(S8只能按一次哦),等时间到了D1灯会不断闪烁表示报警,按S8停止报警
*/
#include
#include
#defineuintunsignedint
#defineucharunsignedchar
sbitkeysource=P1^7;
sbitS5=P2^4;
sbitS6=P2^5;
sbitS7=P2^6;
sbitS8=P2^7;
sbitled0=P3^4;//每按一次任何按键,D2灯会翻转一次状态
sbitled1=P3^5;//闹钟报警用的灯
uintshuju_1;
uintshuju_2;
uintcount;
uintstopwatch_count;
intmiao;
intfen;
intwarn_miao;
intwarn_fen;
uintshanshuo;//1234
bitshanshuo1,shanshuo2,shanshuo3,shanshuo4;
uintnum_settime_cnt;//标识按键5设置时间时,按下的次数
uintnum_setmode_cnt;//1or2
uintstopwatch_miao;
uintstopwatch_Umiao;
uintstopwatch_miao_1;
uintstopwatch_Umiao_1;
uintmode_flag;
uintwarn_flag;
uintstopflag=1;//初始时先让秒表停止
ucharcodeshuma[]={
0xC0,/*0*/
0xF9,/*1*/
0xA4,/*2*/
0xB0,/*3*/
0x99,/*4*/
0x92,/*5*/
0x82,/*6*/
0xF8,/*7*/
0x80,/*8*/
0x90,/*9*/
};//共阳数码管
voiddelay(uintz)//1ms
{
uintx,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
voiddisplay_1()//上排
{
ucharqian,bai,shi,ge;
qian=shuju_1/1000;
bai=shuju_1%1000/100;
shi=shuju_1%100/10;
ge=shuju_1%10;
////xianshi1////
P2|=0xf0;//高4位全部置1
P2&=0xef;//改变高4位,低4位不变
if(shanshuo1==1)
P0=0xff;
else
P0=shuma[qian];
delay
(1);
////xianshi2////
P2|=0xf0;
P2&=0xdf;
if(shanshuo2==1)
P0=0xff;
else
P0=shuma[bai]&0x7f;//要点亮小数点
delay
(1);
////xianshi3////
P2|=0xf0;
P2&=0xbf;
if(shanshuo3==1)
P0=0xff;
else
P0=shuma[shi];
delay
(1);
////xianshi4////
P2|=0xf0;
P2&=0x7f;
if(shanshuo4==1)
P0=0xff;
else
P0=shuma[ge];
delay
(1);
P2=0xff;//解除位选
}
voiddisplay_2()//下排
{
ucharqian,bai,shi,ge;
qian=shuju_2/1000;
bai=shuju_2%1000/100;
shi=shuju_2%100/10;
ge=shuju_2%10;
////xianshi1////
P2|=0x0f;//低4位全部置1
P2&=0xfe;//改变低4位,高4位不变
if(shanshuo1==1)
P0=0xff;
else
P0=shuma[qian];
delay
(1);
////xianshi2////
P2|=0x0f;
P2&=0xfd;
if(shanshuo2==1)
P0=0xff;
elseif(mode_flag==2)
{P0=shuma[bai]&0x7f;}
else
{P0=shuma[bai];}
delay
(1);
////xianshi3////
P2|=0x0f;
P2&=0xfb;
if(shanshuo3==1)
P0=0xff;
elseif(mode_flag==1)
{P0=shuma[shi]&0x7f;}
else
{P0=shuma[shi];}
delay
(1);
////xianshi4////
P2|=0x0f;
P2&=0xf7;
if(shanshuo4==1)
P0=0xff;
else
P0=shuma[ge];
delay
(1);
P2=0xff;//解除位选
}
voidcheck_ledflash()//判断哪一位正在设置中,让该位闪烁
{
switch(shanshuo)//利用shanshuo标志来判断,当前正在在哪一位设定
{
case1:
shanshuo1=~shanshuo1;//如果为第一位,则第一位闪烁,其它位不闪烁
shanshuo2=0;
shanshuo3=0;
shanshuo4=0;
break;
case2:
shanshuo2=~shanshuo2;//如果为第二位,则第一位闪烁,其它位不闪烁
shanshuo1=0;
shanshuo3=0;
shanshuo4=0;
break;
case3:
shanshuo3=~shanshuo3;//如果为第三位,则第一位闪烁,其它位不闪烁
shanshuo1=0;
shanshuo2=0;
shanshuo4=0;
break;
case4:
shanshuo4=~shanshuo4;//如果为第四位,则第一位闪烁,其它位不闪烁
shanshuo1=0;
shanshuo2=0;
shanshuo3=0;
break;
default:
shanshuo1=0;
shanshuo2=0;
shanshuo3=0;
shanshuo4=0;
break;
}
}
voidsettime()//设定系统时间,时间格式:
分-分。
-秒-秒
{
while
(1)//死循环,设定完了才可以退出该循环
{
shuju_1=100*fen+miao;
display_1();
if(!
S5)//移位
{
while(!
S5);
led0=~led0;
num_settime_cnt++;
if(num_settime_cnt>3)num_settime_cnt=0;
}
if(!
S6)//加1
{
while(!
S6);
led0=~led0;
switch(num_settime_cnt)//判断须改变的是哪一位
{case0:
fen=fen+10;//系统时间分钟的十位
shanshuo=1;
break;
case1:
fen=fen+1;//系统时间分钟的个位
shanshuo=2;
break;
case2:
miao=miao+10;//系统时间秒的十位
shanshuo=3;
break;
case3:
miao=miao+1;//系统时间秒的个位
shanshuo=4;
break;
default:
break;
}
}
if(!
S7)//减1
{
while(!
S7);
led0=~led0;
switch(num_settime_cnt)//判断须改变的是哪一位
{case0:
fen=fen-10;
shanshuo=1;
//if(fen<10)fen+=10;
break;
case1:
fen=fen-1;
shanshuo=2;
//if(fen<0)fen=0;
break;
case2:
miao=miao-10;
shanshuo=3;
//if(miao<10)miao+=10;
break;
case3:
miao=miao-1;
shanshuo=4;
//if(miao<0)miao=0;
break;
default:
break;
}
}
if(!
S8)//确定时间设定
{
while(!
S8);
led0=~led0;
shanshuo=0;
break;//跳出最内层循环括号,完成时间设置
}
}
}
voidmode_1()//秒表模式时间格式秒-秒-秒。
-百毫秒
{
while
(1)//最后一个死循环,程序在这里一直运行
{
//TR1=0;//定时器1暂时不启动
mode_flag=1;
shuju_1=100*fen+miao;
display_1();//上排最常走时间
if(stopflag==0)//开始后,一直显示当前走秒的时间
{
shuju_2=10*stopwatch_miao+stopwatch_Umiao;
display_2();//显示闹钟值
}
if(stopflag==1)//如此停止按键按下,保存当前时间,一直显示它
{
shuju_2=10*stopwatch_miao_1+stopwatch_Umiao_1;
display_2();//显示闹钟值
}
if(!
S6)//开始按键
{
while(!
S6);
led0=~led0;
stopflag=0;//开始计时
TR1=1;//定时器1启动
}
if(!
S7)//停止按键
{
while(!
S7);
led0=~led0;
stopflag=1;//秒表停止
TR1=1;//定时器1关闭
stopwatch_Umiao_1=stopwatch_Umiao;
stopwatch_miao_1=stopwatch_miao;
}
if(!
S8)//清零按键
{
while(!
S8);
led0=~led0;
stopflag=1;//秒表停止
TR1=1;//定时器1关闭
stopwatch_Umiao=0;//将走秒值和停止走秒的时刻全清零
stopwatch_miao=0;
stopwatch_Umiao_1=0;
stopwatch_miao_1=0;
}
}
}
voidmode_2()//设定闹钟时间,时间格式:
分-分。
-秒-秒
{
num_settime_cnt=0;//设置完上排时间后,num_settime_cnt可能不为0,这里清除它
while
(1)//最后一个死循环,程序在这里一直运行
{
mode_flag=2;
shuju_1=100*fen+miao;
display_1();//上排最常走时间
shuju_2=100*warn_fen+warn_miao;
display_2();//显示闹钟值
if(shuju_1==shuju_2)warn_flag=2;
if(!
S5)//控制移位
{
while(!
S5);
led0=~led0;
num_settime_cnt++;
if(num_settime_cnt>3)num_settime_cnt=0;
}
if(!
S6)//闹钟的该位加1
{
while(!
S6);
led0=~led0;
switch(num_settime_cnt)//判断须改变的是哪一位
{case0:
warn_fen=warn_fen+10;
shanshuo=1;
break;
case1:
warn_fen=warn_fen+1;
shanshuo=2;
break;
case2:
warn_miao=warn_miao+10;
shanshuo=3;
break;
case3:
warn_miao=warn_miao+1;
shanshuo=4;
break;
default:
break;
}
}
if(!
S7)//闹钟的该位减1
{
while(!
S7);
led0=~led0;
switch(num_settime_cnt)//判断须改变的是哪一位
{case0:
warn_fen=warn_fen-10;
shanshuo=1;
break;
case1:
warn_fen=warn_fen-1;
shanshuo=2;
break;
case2:
warn_miao=warn_miao-10;
shanshuo=3;
break;
case3:
warn_miao=warn_miao-1;
shanshuo=4;
break;
default:
break;
}
}
if(!
S8)
{
while(!
S8);
led0=~led0;
shanshuo=0;
warn_flag++;//第一次按S8确认闹钟设置,第二次按取消闹钟,警示灯会停止闪动
}
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////
voidmain()
{
TMOD=0x01;//定时器0,定时器1为工作方式1
TH0=(65535-45872)/256;//11.05926M,50msis45872
TL0=(65535-45872)%256;
TH1=(65535-972)/256;//定时器装初值,须在中断里重装初值
TL1=(65535-972)%256;
EA=1;//开总中断
ET0=1;//开定时器0中断
ET1=1;//开定时器0中断
TR0=1;//启动定时器0
TR1=0;//定时器1暂时不启动
shuju_1=0;//显示清零
shuju_2=0;
keysource=0;//P17作为按键输入源电压
settime();//设置上排显示时间
while
(1)
{
display_1();
shuju_1=100*fen+miao;//设置完时间后,上排不能关
display_2();//下排显示模式选择
if(!
S5)//模式选择:
1,秒表;2,闹钟
{
while(!
S5);
led0=~led0;
num_setmode_cnt++;
if(num_setmode_cnt>2)num_setmode_cnt=1;//使选择的模式在1和2之间来回切换
if(num_setmode_cnt==1)
{
shuju_2=1000;//最高位显示1
}
if(num_setmode_cnt==2)
{
shuju_2=2000;//最高位显示2
}
}
if(!
S8)//确认模式选择:
1,秒表;2,闹钟
{
while(!
S8);
if(num_setmode_cnt==1)
{
mode_1();//秒表模式
}
if(num_setmode_cnt==2)
{
mode_2();//闹钟模式
}
}
}
}
voidT0_time()interrupt1//定时器0中断产生时钟
{
TH0=(65535-45872)/256;//reload
TL0=(65535-45872)%256;
count++;
if(count%4==0)//D1,闹钟报警时才使用,闪烁更快
{if(warn_flag==2)led1=~led1;}
if(count==25)//一秒钟到达
{
count=0;
miao++;
if(miao==60)//每60秒进位成一分钟
{
fen++;
miao=0;
}
check_ledflash();//检查是否需要闪烁数字
if(warn_flag==2)led1=~led1;
}
}
voidT1_time()interrupt3//定时器1中断产生秒表时钟
{
TH1=(65535-9972)/256;//reload
TL1=(65535-9972)%256;
stopwatch_count++;
if(stopwatch_count==100)//0.1秒钟到达
{
stopwatch_count=0;
stopwatch_Umiao++;
if(stopwatch_Umiao==10)//进位
{
stopwatch_Umiao=0;
stopwatch_miao++;
}
check_ledflash();//检查是否需要闪烁数字
}
}