/*
程序功能:60秒LED旋转显示的电子钟程序,可调时间,且能定时响闹,
作者:于海超 (转载请注明出处)
*/
#include<reg52.h>
#include <intrins.h>
#define uint unsigned int
#define uchar unsigned char
uchar temp1,temp2,aa,bb,K1num,K2num,K1K2num;
uint miao,fen,fen1,shi,shi1;fenge,fenshi,shige,shishi,fen1ge,fen1shi,shi1ge,shi1shi,N,flag1,flag2,flag3,flag4;
uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//共阴数码管的编码
sbit K1=P1^0; //两个按键
sbit K2=P1^1;
sbit beep=P1^2; //蜂鸣器
sbit B4=P1^4; //四位数码管的位选端
sbit B5=P1^5;
sbit B6=P1^6;
sbit B7=P1^7;
void init(); //声明初始化函数
void delay(uint z); //声明延时函数
void display(uint fenge,uint fenshi,uint shige,uint shishi); //声明显示函数
void keyscan(); //声明键盘扫描函数
void main()
{
init();//初始化子程序
while(1)
{
keyscan();
fenge=fen%10; //取分钟的个位,下同
fenshi=fen/10; //取分钟的十位,下同
shige=shi%10;
shishi=shi/10;
fen1ge=fen1%10;
fen1shi=fen1/10;
shi1ge=shi1%10;
shi1shi=shi1/10;
if(flag4==1) display(fenge,fenshi,shige,shishi);
else display(fen1ge,fen1shi,shi1ge,shi1shi);
}
}
void delay(uint z) //延时函数
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
void init() //初始化函数
{
aa=0; //中断累加次数初始化
bb=0;
K1num=0;
K2num=0;
K1K2num=0;
miao=0; //系统时间初始化
fen=0;
shi=0;
N=0; //N用于控制校时或定闹时时间闪烁显示,以提醒为校时或是定闹状态
fen1=1; //定时时间初始化
shi1=0;
flag1=1; //flag1=1用于标记闹钟没有响闹,flag1=0用于标记闹钟正在响闹,这两种情况下按下K2键所起的作用是不一样的
flag2=1; //闹钟是否响闹的一个标记变量,如果flag2=1,则闹钟时间到,闹钟响闹,如果此时按下K2键,将置flag2=0,是闹钟停止响闹
flag3=1; //flag3用于控制当调整闹钟时间时,闹钟不可以响闹
flag4=1; //flag4=1用于控制调用显示函数显示的是系统的时间,flag4=0用于控制当K2被按下后,调用显示函数显示的是定时的时间
beep=0; //蜂鸣器初始化
temp1=0xfe; //点亮LED的初始化,点亮第一组第一个
temp2=0x01; //点亮LED的初始化,选中第一组
P3=temp2;
P2=temp1;
TMOD=0x01;//设置定时器0为工作方式1
TH0=(65536-50000)/256; //计数器装入初值
TL0=(65536-50000)%256;
EA=1;//开总中断
ET0=1;//开定时器0中断
TR0=1;//启动定时器0
}
void keyscan() //键盘扫描函数
{
if(K2==0&&flag1==0); //flag1=0代表此时闹钟正在响闹,如果按下K2键,则使闹钟停止响闹
{
delay(5);
if(K2==0)
{
flag2=0; //定闹键按下,停止闹钟
}
}
if(K1==0&&K2num==0) //判断K1按下,按下前没有按下K2键,则开始修改系统时间
{
delay(5);
if(K1==0)
{
TR0=0; //关闭计数器0
N=500; //N=500用于控制校时或定闹时时间闪烁显示,以提醒为校时或是定闹状态
K1num++; //K1按键次数累加
while(!K1)
if(K1num==1)
{
//第一次按下校时键调整分钟,见下面的代码
}
if(K1num==2)
{
//第二次按下校时键时,调整小时,见下面的代码
}
if(K1num==3) //第三项按下校时键,系统时间调解完毕,
{
N=0; //数码管不再显示
K1num=0; //清零K1num
TR0=1; //开启定时器
}
}
}
if((K2==0)&&(K1num==0)&&(flag1==1)) //判断K2按下,按下前没有按下K1键,并且闹钟没有响闹,则开始修改闹钟时间
{
delay(5);
if(K2==0)
{
N=500; //N=500用于控制校时或定闹时时间闪烁显示,以提醒为校时或是定闹状态
K2num++; //K2按键次数累加
flag3=0; //flag3=0用于控制当调整闹钟时间时,闹钟不可以响闹
flag4=0; //flag4=0用于控制当K2被按下后,调用显示函数显示的是定时的时间
while(!K2)
if(K2num==1)
{
//第一次按下定闹键调整分钟
}
if(K2num==2)
{
//第二次按下定闹键调整小时
}
if(K2num==3)
{
N=0; //N=0用于控制校时或定闹时时间停止闪烁
K2num=0;
flag3=1;
flag4=1;
}
}
}
if(K1num!=0) //当按下K1键后
{
if(K2==0) //判断是否按下K2键
{
delay(5);
if(K2==0)
{
while(!K2);
if(K1num==1) //如果按下K2键,且K1键被第一次按下,则修改电子钟的系统时间的分钟
{
fen++;
if(fen==60)
fen=0;
}
if(K1num==2) //如果按下K2键,且K1键被第二次按下,则修改电子钟的系统时间的小时
{
shi++;
if(shi==24)
shi=0;
}
}
}
}
if(K2num!=0) //当按下K2键后
{
if(K1==0) //判断是否按下K1键
{
delay(5);
if(K1==0)
{
while(!K1);
if(K2num==1) //如果按下K1键,且K2键被第一次按下,则修改电子钟的闹钟时间的分钟
{
fen1++;
if(fen1==60)
fen1=0;
}
if(K2num==2) //如果按下K1键,且K2键被第二次按下,则修改电子钟的闹钟时间的小时
{
shi1++;
if(shi1==24)
shi1=0;
}
}
}
}
}
void time0() interrupt 1 //定时器0中断服务程序
{
TH0=(65536-50000)/256; //定时器重新装入数值
TL0=(65536-50000)%256;
aa++; //中断次数累加
if(aa==20) //20次50毫秒为1秒
{
aa=0;
bb++; //数码管分为8组,7组8个的,一组四个的,共60个LED
miao++;
temp1=_crol_(temp1,1); //过1秒,下一个LED亮,temp1与temp2相当于段选与位选的关系
if(bb==8) //当每组的8个LED全部点亮后,点亮下一组
{
bb=0;
temp2=_crol_(temp2,1);//移位至下一组
P2=0xff; //消隐,防止进入下一组时LED被错误点亮
P3=temp2; //移位至下一组
}
P2=temp1; //开始点亮下一组的数码管
if(miao==60)
{
fen++;
flag2=1;//闹钟响起时按下K2键闹钟关闭,此处应重置该变量,使下一次闹钟时间来到时,闹钟仍热可以响起
flag1=1;//闹钟响起时按下K2键闹钟关闭,此处应重置该变量,使下一次闹钟时间来到时,K2按下,仍可以使闹钟停止发音
aa=0; //中断累加次数清零
bb=0; //位选清零
miao=0;
temp1=0xfe; //初始化LED个
temp2=0x01; //初始化LED组
P3=temp2;
P2=temp1;
if(fen==60)
{
fen=0;
shi++;
if(shi==24)
{
shi=0;
}
}
}
}
if((fen==fen1)&&(shi==shi1)&&(flag2==1)&&(flag3==1)) //闹钟的响闹控制,flag3=0用于控制当调整闹钟时间时,闹钟不可以响闹
{
beep=1;
flag1=0;
}
else beep=0;
}
void display(uint fenge,uint fenshi,uint shige,uint shishi) //数码管显示函数
{
P0=0; //消隐,后同
B4=1;B5=1;B6=1;B7=0;//控制数码管的位选,采用数码管动态显示技术,后同
P0=table[fenge]; //显示分钟的个位
delay(5);
P0=0;
B4=1;B5=1;B6=0;B7=1;
P0=table[fenshi]; //显示分钟的十位
delay(5);
P0=0;
B4=1;B5=0;B6=1;B7=1;
P0=table[shige]; //显示小时的个位
delay(5);
P0=0;
B4=0;B5=1;B6=1;B7=1;
P0=table[shishi]; //显示小时的十位
delay(5);
B4=1;B5=1;B6=1;B7=1;
delay(N); //N用于控制校时或定闹时时间闪烁显示,以提醒为校时或是定闹状态
}
- 1
- 2
- 3
- 4
前往页