#include<stdlib.h>
#include<stdio.h>
#include<reg52.h>
sbit key=P1^0;
sbit led=P1^1;
typedef unsigned char byte;
typedef unsigned int word;
static byte disp[4];
code byte table[]={/*0,1,2,3,4,5,6,7,8,9,*/
0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,
};//数码管表
/*子函数*/
byte bot()
{
if(key==0)
return 0;
else
return 1;
}
void display(word ms) //数码管上的显示反应时间
{
byte posi=0x01,i,j,temp;
disp[3]=ms/1000; //千位
disp[2]=(ms%1000)/100; //百位
disp[1]=(ms%100)/10; //十位
disp[0]=ms%10; //个位
for(i=0;i<4;i++) //数码管显示
{
temp=disp[i];
temp=table[temp];
for(j=0;j<100;j++) //延时
{
P2=posi; //四个数码管显示数字(动态扫描)
P0=temp; //一个数码管显示数字
}
posi=posi*2; //动态扫描
}
}
unsigned long random()
{
word rt;
byte k=0;
srand (50000); //种下随机数种子,范围0-50000
rt=rand(); //生成随机熟
rt=rt*rand(); //使随机数足够大,能够延时足够时间
return rt;
}
void INIT_TMR1()
{
TMOD=0x10; //用的T1,工作方式1(16位计数器)
TH1=0xfc;
TL1=0x18;
TR1=1; //打开定时计数器
}
/*主函数*/
void main()
{
byte k=0;
k=bot(); //获取按键情况
P1=0xff; //输入前先把P1口都加高电平
while(1) //主循环开始
{
word ms=0,j;
word r;
while(bot()); //等待按键按下,否则始终等待
led=0; //按键被按下后,灯亮
r=random();
for (j=r;j>0;--j) //延时一段随机时间
{
k=bot();
if (k==1) //如果在灯灭前谈起按键,显示最长时间作为惩罚
{
ms=9999;
goto loop;
}
}
led=1; //灯灭
INIT_TMR1(); //初始定时状态
while(1) //如果按键弹起,反复进入定时状态,每1ms计时器溢出一次,毫秒数加1
{
if(TF1==1)
{
TH1=0xfc;
TL1=0x18;
TR1=1;
TF1=0;
++ms;
}
if(k=bot()) break;
}
loop: led=1 ;
while(1)
{
if(k==1) //按键弹开后始终显示时间
{
k=bot();
display(ms);
}
else //若按键按下,重新开始测试
{
ms=0;
P2=0xff;
break;
}
}
}
}