/**********************************************************************************
此程序利用八位共阳数码管显示的时钟具有时钟、调时、调闹钟的功能,实现八位数码管单独
位校准,同时校准时数码管闪烁。
key4----计时开关,(主要控制TR0是1或0,即LED灯的亮或灭)。
初始值0,按下后取反,开始计时,再按,停止计时。
key1----模式选择,标志位flg,取值1、2、0。
初始值0,正常显示时钟走时;
按一下,flg=1,时钟调整模式,按两下,flg=2,闹钟调整模式;
按三下,flg=0;回到正常时钟模式。依次循环。
key2----校准位选择,标志位flg1,取值0~8.
初始值为0;哪一位都不闪烁,哪一位都不校准;
每按一下,则flg1+1,加到8,再按一下回到flg1=0;
flg1=1,表示校准第一位,第一位闪烁;flg1=2,校准第二位,第二位闪烁,依次……
key3----校准控制位,控制改变每一位数码管所显示的数字,校准哪一位,则按key3改变哪一位的值。
******************************************************************************************
定时器0用来产生计时,定时器1用来控制闪烁标志位flg2
******************************************************************************************
由于匆忙,未加入闹钟,不过这不是最主要的问题。在
电路实际运行中,发现一些问题不足,求大神
高手指点迷津。谢谢!!!!!!!!!!!!!!!!!!!!!!!
现象描述:
a. 上电后,按key4,启动计时;
b. 按key1,选择调校时钟,
c. 按key2,控制校准位选择
d. 按key3,改变校准位的值
e. 反复按key2,
f. 反复按key4,
g. 按Key1,使之回到正常时钟计时模式,反复按key4,;
问题:1、重复e.f两个步骤,则会出现“明明已经开启计时模式,led亮,即TR0=1,但最后一位秒位
要十几秒才反应过来继续改变数值计时”的情况“
2、操作g步骤,同样遇到上述问题
***********************************************************************************
疑惑 1、产生上述问题的根源是什么???这是否与启用两个定时器设置有关????
2、使用两个定时器时应该注意哪些问题???此处我令两个定时器初值都一样,是否不当?
3、定时器0和定时器1有中断先后优先级,初始化时是否需要配置IP???
***********************************************************************************/
#include<reg52.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit voice=P2^3;
sbit DU=P2^6;
sbit WE=P2^7;
sbit key1=P3^0;
sbit key2=P3^1;
sbit key3=P3^2;
sbit key4=P3^3;
uchar cnt;
char flg,flg1;//flg按Key2,一次时钟调整模式flg=1,两次定闹钟调整模式flg=2,三次正常时钟模式flg=0;
//flg1用来选择校准位;
bit flg2; //flg2用来闪烁标志位,bit只有0和1两种状态。
//TR0=1,则令P1=0x00,led亮,反之,TR0=1,则令P1=0xff,led灭,便于直观看出是否启动计时
uchar shi,fen,miao;//设定时钟
uchar hour,minute,second;//设定闹钟
uchar code duan[]={
0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x00,0x40};
//段选 0 1 2 3 4 5 6 7 8 9 A b C D E F 灭 -
uchar code T_COM[]={
0xff,0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};
//位选 灭 第一 二 三 四 五 六 七 八位
uchar table[]={0,1,2,17,4,5,17,7,8,9,10,17,12,13,17,15,16};//显示哪一位
void delayms(char xms)
{
uchar i,j;
for(i=xms;i>0;i--)
for(j=110;j>0;j--);
}
void init()
{
TMOD=0x11;
TH0=(65536-46080)/256;
TL0=(65536-46080)%256;//定时50ms
TH0=(65536-46080)/256;
TL0=(65536-46080)%256;//定时50ms
EA=1;
ET0=1;
ET1=1;
TR1=1;
shi=18;
fen=1;
miao=0;
DU=0;
WE=0;
}
void keyscan()//shi+10;shi+1;fen+10;fen+1;miao+10;miao+1
{
if(key1==0)
{
delayms(10);
if(key1==0)
{
flg++;
if(flg>2)
flg=0;
while(!key1);
}
}
if(key2==0)
{
delayms(10);
if(key2==0)
{
flg1++;
if(flg1>8)
flg1=1;
while(!key2);
}
}
if(key3==0)
{
delayms(10);
if(key3==0)
{
if(flg==1)
{
switch(flg1)
{
case 1: if(shi<13)
shi+=10;
else if(shi<20&shi>13)
shi-=10;
else if(shi>20)
shi-=20; break;
case 2: if(shi<20)
{
if(shi%10==9)
shi-=9;
else
shi+=1;
}
else
{
if(shi%10==3)
shi-=3;
else
shi+=1;
} break;
case 3: break;
case 4: if(fen>=50)
fen-=50;
else
fen+=10; break;
case 5: if(fen%10==9)
fen-=9;
else
fen+=1; break;
case 6: break;
case 7: if(miao>=50)
miao-=50;
else miao+=10; break;
case 8: if(miao%10==9)
miao-=9;
else
miao+=1; break;
}
}
else if(flg==2)
{
switch(flg1)
{
case 1: if(hour<=13)
hour+=10;
else if(hour<20&hour>13)
hour-=10;
else if(hour>20)
hour-=20; break;
case 2: if(hour<20)
{
if(hour%10==9)
hour-=9;
else
hour+=1;
}
else
{
if(hour%10==3)
hour-=3;
else
hour+=1;
} break;
case 3: break;
case 4: if(minute>=50)
minute-=50;
else
minute+=10; break;
case 5: if(minute%10==9)
minute-=9;
else
minute+=1; break;
case 6: break;
case 7: if(second>=50)
second-=50;
else
second+=10; break;
case 8: if(second%10==9)
second-=9;
else
second+=1; break;
}
}
while(!key3);
}
}
if(key4==0)
{
delayms(10);
if(key4==0)
{
TR0=~TR0;
while(!key4);
}
}
}
void caculate()
{
table[1]=shi/10;
table[2]=shi%10;
table[4]=fen/10;
table[5]=fen%10;
table[7]=miao/10;
table[8]=miao%10;
table[9]=hour/10;
table[10]=hour%10;
table[12]=minute/10;
table[13]=minute%10;
table[15]=second/10;
table[16]=second%10;
}
void display()
{
uchar i;
for(i=1;i<=8;i++)
{
WE=1;
P0=T_COM[i];
WE=0;
P0=0x00;
DU=1;
if(flg<2)
{
if(flg1==i&&flg2==1)
P0=0x00;
else
P0=duan[table[i]];
}
else
{
if(flg1==i&&flg2==1)
P0=0x00;
else
P0=duan[table[i+8]];
}
DU=0;
delayms(10);
P0=0xff;
}
}//此处针对
proteus仿真所编写,实际板子中的display程序稍微不同,此处不影响 不必深究
void main()
{
init();
while(1)
{
keyscan();
if(!flg)
flg1=0;
keyscan();
if(cnt==20)
{
cnt=0;
miao++;
}
if(miao>59)
{
miao=0;
fen++;
}
if(fen>59)
{
fen=0;
shi++;
}
if(shi>23)
shi=0;
if(TR0)
P1=0x00;
else
P1=0xff;
caculate();
display();
}
}
void
timer0() interrupt 1
{
TH0=(65536-46080)/256;
TL0=(65536-46080)%256;//定时50ms
cnt++;
}
void timer1() interrupt 3
{
TH1=(65536-46080)/256;
TL1=(65536-46080)%256;//定时50ms
cnt++;
if(cnt==5)
{
cnt=0;
flg2=~flg2;
}
}
/* 如下为另一种显示方法,不完整,可忽略不看
void display(uchar x,y,z)
{
uchar i;
for(i=1;i<=8;i++)
{
WE=1;
P0=T_COM[i];
WE=0;
P0=0x00;
DU=1;
switch(i)
{
case 1:P0=duan[x/10];break;
case 2:P0=duan[x%10];break;
case 3:P0=duan[17];break;
case 4:P0=duan[y/10];break;
case 5:P0=duan[y%10];break;
case 6:P0=duan[17];break;
case 7:P0=duan[z/10];break;
case 8:P0=duan[z%10];break;
}
DU=0;
delayms(10);
P0=0xff;
}
if(flg1==i)
{
WE=1;
P0=T_COM[i];
WE=0;
P0=0x00;
DU=1;
P0=0x00;
DU=0;
delayms(10) ;
P0=0xff;
}
}
void all_display(uchar i)
{
switch(i)
{
case 0:display(shi,fen,miao);break; //正常显示时钟
case 1:display(shi,fen,miao);break; //时钟设定
case 2:display(hour,minute,second);break;//闹钟设定
}
}
//all_display(flg);
*/
-
-
Proteus 仿真fangzhen_clock.rar
下载积分: 积分 -1 分
67.5 KB, 下载次数: 14, 下载积分: 积分 -1 分
一周热门 更多>