用51单片机C语言怎样编程,可以实现切换两个四位共阴数码管时分秒的调试?

不用锁存器,我现在用中断来写的,用了四个独立按键只能编到可以调试时的,然后就不会切换到调分与秒的了,并且要按住按键1才能调。这是我的程序:
#include <reg52.h>
#define unchar unsigned char
#define unint unsigned int
void display(unint shi,unint fen,unint miao);
void keyscan();
sbit key1=P1^0;
sbit key2=P1^1;
sbit key3=P1^2;
sbit key4=P1^3;
unint shi,fen,miao,num;
void delay(float z);
unchar table[]={0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f
};//数码管字形表,0-9

void main()
{
TMOD=0x01; //工作方式1
TH0=(65536-50000)/256;//50ms一次中断
TL0=(65536-50000)%256;
EA=1; //开总中断
ET0=1;//开定时器0中断
TR0=!TR0;

while(1)
{
keyscan();
display(shi,fen,miao);
}
}
void display(unint shi,unint fen,unint miao)
{ P2=0x7f;
P0=table[miao%10];
delay(1);
P2=0xbf;
P0=table[miao/10];
delay(1); //秒位完毕

P2=0xdf;
P0=0x40;//秒与分之间的杠
delay(1);

P2=0xef;
P0=table[fen%10];
delay(1);
P2=0xf7;
P0=table[fen/10];
delay(1);//分位完毕

P2=0xfb;
P0=0x40;//分与时之间的杠
delay(1);

P2=0xfd;
P0=table[shi%10];
delay(1);
P2=0xfe;
P0=table[shi/10];
delay(1);//时位完毕
} /* */
void inter0()interrupt 1
{
TH0=(65536-50000)/256;
TH1=(65536-50000)%256;
num++;
if(num==20)
{
num=0;
miao++;
if(miao==60)
{
miao=0;
fen++;
if(fen==60)
{
fen=0;
shi++;
if(shi==24)
shi=0;
}
}
}
}

void delay(float z)
{
int y;
for (;z>0;z--)
for(y=110;y>0;y--);
}

void keyscan()
{
if(key4==0)
{
delay(10);
while(!key4);
TR0=!TR0;//启动或关闭定时器0
}
if(key1==0) //按一次调节时
{
delay(10);
if(key2==0)
{
delay(10);
shi++;
if(shi==24)
shi=0;
while(!key2);
}
if(key3==0)
{
delay(10);
shi--;
while(!key3);
}
//while(!key1); 调节时完毕

}

}

思路有点问题。
除思路问题外,键盘扫描的处理也有点问题,去抖没做好。
1,建议定义一个变量status标记当前调整的是“时”还是“分”还是秒。用一个按键控制这个变量的变化,变量的值由0变到3,再变为0。0的时候不调整,1的时候调整时,2的时候调整分,3的时候调整秒.用KEY1控制,按一下KEY1,变量status由常态0变成1,再按变成2,再按就成3,再按变回0。
2,用KEY2做加,KEY3做减。按一个KEY2,当前操作的单元加1 ,(如“时”加一)。按一下KEY3,当前操作的单元减一。
还可以把当前操作的单元显示为闪烁状态。

键盘扫描处理,如扫描KEY1,先看KEY1是否按下,然后延时,然后再次看KEY1是否仍然按下,如果是,则确认KEY1有效,否则认为是抖动。追问

能把你说的那段程序写给我看看吗?我写不出来!谢谢!

追答

#include
#define unchar unsigned char
#define unint unsigned int
void display(unint shi,unint fen,unint miao);
void keyscan();
void delay(float z);
sbit key1=P1^0;
sbit key2=P1^1;
sbit key3=P1^2;
sbit key4=P1^3;
unint shi,fen,miao,num;
volatile status = 0;
unchar table[]={0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f
};//数码管字形表,0-9

//------------------------------------------

void main()
{
}

void display(unint shi,unint fen,unint miao)
{

} /* */

void inter0()interrupt 1
{
TH0=(65536-50000)/256;
TH1=(65536-50000)%256;
num++;
if(num==20)
{
num=0;
miao++;
if(miao==60)
{
miao=0;
fen++;
if(fen==60)
{
fen=0;
shi++;
if(shi==24)
shi=0;
}
}
}
}

//--------------------------------
void delay(float z)
{
int y;
for (;z>0;z--)
for(y=110;y>0;y--);
}

//------------------------------
void keyscan()
{
//处理key4
if(key4==0)
{
delay(10);
while(!key4);
TR0=!TR0;//启动或关闭定时器0
}
//处理key1
if(key1==0) //按一次调节时
{
delay(10); //延时去抖
if(key1==0) //再次确认key1
{
status++;
if(status>3)
{
status = 0;
}
}
}
if(key2==0)
{
delay(10);
if(key2==0)
{
if(status==1)
{
shi++;
if(shi==24)
shi=0;
}
else if(status==2)
{
fen++;
if(fen>59)
{
fen = 0;
}
}
else if(status==3)
{
miao++;
if(miao>59)
{
miao=0;
}
}
while(!key2);

}
}
if(key3==0)
{
delay(10);
if(key3==0)
{
if(status==1)
{
if(shi==0)
shi=24;
shi--;
}
else if(status==2)
{
if(fen==0)
{
fen = 60;
}
fen--;
}
else if(status==3)
{
if(miao==0)
{
miao=60;
}
miao--;
}

while(!key2);
}
}

}

追问

编译时还有点下面的问题:
~
WARNING L16: UNCALLED SEGMENT, IGNORED FOR OVERLAY PROCESS
WARNING L16: UNCALLED SEGMENT, IGNORED FOR OVERLAY PROCESS
LESSON 3-5.C(25): warning C280: 'shi': unreferenced local variable
LESSON 3-5.C(25): warning C280: 'fen': unreferenced local variable
LESSON 3-5.C(25): warning C280: 'miao': unreferenced local variable
~
"lesson 3-5" - 0 Error(s), 5 Warning(s).

追答

因为字数超了,所以我把前面很多东西删了,你只需把键盘扫描那部分替换你原来的程序,然后前面增加一个status的定义就行了。在我这编译没有warning。

温馨提示:答案为网友推荐,仅供参考
第1个回答  2012-05-13
你好,能把你的仿真图发一分给我吗?[email protected]