|
本帖最后由 lilipo 于 2016-9-18 17:33 編輯
/**********************************************************************************
此程序利用八位共陽數碼管顯示的時鐘具有時鐘、調時、調鬧鐘的功能,實現八位數碼管單獨
位校準,同時校準時數碼管閃爍。
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;
WE=0;
P0=0x00;
DU=1;
if(flg<2)
{
if(flg1==i&&flg2==1)
P0=0x00;
else
P0=duan[table];
}
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;
}
}
|
|