我写了一个简单的单片机的四人抢答器,但是十秒倒计时显示0之后他显示1,请帮忙看看是怎么回事,谢谢!
程序如下:
#include
#define uchar unsigned char
#define uint unsigned int
uchar num; //定义中断变量,num计满20表示1秒时间到
uchar num1; //十秒倒计时显示初始值
uchar flag1=0,flag2=0; //清零键及开始键按下标志位
uchar code table[]={
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f}; //数码管编码
sbit dula=P2^6; //定义段选端口
sbit wela=P2^7; //定义位选端口
sbit sp=P2^3; //定义蜂鸣器端口
sbit zero1=P3^0;
sbit zero=P3^1;
sbit key1=P3^4;
sbit key2=P3^5;
sbit key3=P3^6;
sbit key4=P3^7;
sbit clear=P3^4;
sbit start=P3^5;
void delay(uint z) //延时函数
{
uint i,j;
for(i=z;i>0;i--)
for(j=110;j>0;j--);
}
void beep() //定义蜂鸣器函数
{
sp=0;
delay(500);
sp=1;
}
void display(uint a) //选手编号显示函数
{
wela=1;
P0=0xff; //防止锁存干扰
wela=0;
dula=1;
P0=table[a];
dula=0;
P0=0xff;
wela=1;
P0=0xfd;
wela=0;
delay(5);
}
void clr() //清零函数(主持人按下清零键后数码管显示0)
{
dula=1;
P0=table[0];
dula=0;
P0=0xff;
wela=1;
P0=0xfc;
wela=0;
delay(5);
}
void dis10s() //十秒倒计时显示函数
{
uchar shi,ge;
shi=num1/10;
ge=num1%10;
wela=1;
P0=0xff;
wela=0;
dula=1;
P0=table[shi];
dula=0;
P0=0xff;
wela=1;
P0=0xfe;
wela=0;
delay(5);
wela=1;
P0=0xff;
wela=0;
dula=1;
P0=table[ge];
dula=0;
P0=0xff;
wela=1;
P0=0xfd;
wela=0;
delay(5);
}
void player() //选手按键检测函数
{
zero1=0;
if(key1==0)
{
delay(10);
if(key1==0)
{
zero1=1;
TR0=0;
display(1);
flag1=flag2=0;
beep();
}
}
if(key2==0)
{
delay(10);
if(key2==0)
{
zero1=1;
TR0=0;
display(2);
flag1=flag2=0;
beep();
}
}
if(key3==0)
{
delay(10);
if(key3==0)
{
zero1=1;
TR0=0;
display(3);
flag1=flag2=0;
beep();
}
}
if(key4==0)
{
delay(10);
if(key4==0)
{
zero1=1;
TR0=0;
display(4);
flag1=flag2=0;
beep();
}
}
}
void keyscan() //检测按键
{
zero=0;
if(clear==0&&flag2!=1) //判断清零键
{
delay(10);
if(clear==0&&flag2!=1)
{
flag1=0;
flag2=0;
num=0;
num1=10;
clr(); //清零
flag1=1; //按下清零键标志位
}
}
if(flag1==1) //如果按下清零键
{
if(start==0) //判断开始键
{
delay(10);
if(start==0)
{
flag2=1;
}
}
}
if(flag2==1) //按下开始键
{
flag1=0;
zero=1;
TR0=1; //启动定时器0
dis10s();
player();
}
}
void main()
{
TMOD=0x01; //设置定时器0工作方式1
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
EA=1; //开总中断
ET0=1; //开定时器0中断
while(1) //一直检测按键
{
keyscan();
}
}
void T0_ser() interrupt 1
{
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
num++;
if(num==20)
{
num=0;
num1--;
}
if(num1==0)
{
TR0=0;
flag1=0;
flag2=0;
num=0;
num1=10;
clr();
beep();
clr();
}
}
引用: 引用 1 楼 ouyangjinlin 的回复:
有原理图么?程序太多,我写程序是按原理图写的。
有原理图,好像前面程序发错了,现在重新发,原理图在最下面
#include
#define uchar unsigned char
#define uint unsigned int
uchar num; //定义中断变量,num计满20表示1秒时间到
uchar num1; //十秒倒计时显示初始值
uchar flag1,flag2; //清零键及开始键按下标志位
uchar code table[]={
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f}; //数码管编码
sbit dula=P1^6; //定义段选端口
sbit wela=P1^7; //定义位选端口
sbit sp=P3^0; //定义蜂鸣器端口
sbit clear=P1^0; //定义清零键
sbit start=P1^1; //开始键
sbit key1=P1^2;
sbit key2=P1^3;
sbit key3=P1^4;
sbit key4=P1^5; //key1到key4为选手按键
void delay(uint z) //延时函数
{
uint i,j;
for(i=z;i>0;i--)
for(j=110;j>0;j--);
}
void beep() //定义蜂鸣器函数
{
sp=0;
delay(500);
sp=1;
}
void display(uint a) //选手编号显示函数
{
wela=1;
P2=0xff; //防止锁存干扰
wela=0;
dula=1;
P2=table[a];
dula=0;
P2=0xff;
wela=1;
P2=0xfd;
wela=0;
delay(5);
}
void clr() //清零函数(主持人按下清零键后数码管显示0)
{
dula=1;
P2=table[0];
dula=0;
P2=0xff;
wela=1;
P2=0xfc;
wela=0;
delay(5);
}
void dis10s() //十秒倒计时显示函数
{
uchar shi,ge;
shi=num1/10;
ge=num1%10;
wela=1;
P2=0xff;
wela=0;
dula=1;
P2=table[shi];
dula=0;
P2=0xff;
wela=1;
P2=0xfe;
wela=0;
delay(5);
wela=1;
P2=0xff;
wela=0;
dula=1;
P2=table[ge];
dula=0;
P2=0xff;
wela=1;
P2=0xfd;
wela=0;
delay(5);
}
void player() //选手按键检测函数
{
if(key1==0)
{
delay(10);
if(key1==0)
{
TR0=0;
display(1);
flag1=flag2=0;
beep();
}
}
if(key2==0)
{
delay(10);
if(key2==0)
{
TR0=0;
display(2);
flag1=flag2=0;
beep();
}
}
if(key3==0)
{
delay(10);
if(key3==0)
{
TR0=0;
display(3);
flag1=flag2=0;
beep();
}
}
if(key4==0)
{
delay(10);
if(key4==0)
{
TR0=0;
display(4);
flag1=flag2=0;
beep();
}
}
}
void keyscan() //检测按键
{
if(clear==0&&flag2!=1) //判断清零键
{
delay(10);
if(clear==0&&flag2!=1)
{
flag1=0;
flag2=0;
num=0;
num1=10;
clr(); //清零
flag1=1; //按下清零键标志位
}
}
if(flag1==1) //如果按下清零键
{
if(start==0) //判断开始键
{
delay(10);
if(start==0)
{
flag2=1;
}
}
}
if(flag2==1) //按下开始键
{
TR0=1; //启动定时器0
dis10s();
player();
}
}
void main()
{
TMOD=0x01; //设置定时器0工作方式1
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
EA=1; //开总中断
ET0=1; //开定时器0中断
while(1) //一直检测按键
{
keyscan();
}
}
void T0_ser() interrupt 1
{
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
num++;
if(num==20)
{
num=0;
num1--;
}
if(num1==0)
{
TR0=0;
flag1=0;
flag2=0;
num=0;
num1=10;
clr();
beep();
}
}