效果图
//功能:在限定时间内(20秒),每间隔1秒随机点亮D1-D8,要求在间隔时间1秒内迅速点击对应的按键,
//1秒时间到,则进入下一轮;当20秒时间到时,统计击中的胜率,并给出评价:
//好:胜率>=80%; 中:50%<=胜率<80%; 差:胜率<50%;
#include <reg52.h>
#include<stdlib.h>//随机函数在里面
#include <stdio.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
volatile uchar state=0;//全局状态标识变量
volatile uchar test_state=0;//测试状态标识变量
volatile uint flag=0;
volatile uint interval_time_length=0;
uint time_counter_interval;//2ms定时情况下,0.5秒时间到的判读计数器
uint time_counter_overall; //2ms定时情况下,10秒时间到的判读计数器
sbit led_good=P3^2; //好评灯控制端口
sbit led_normal=P3^3;//中评灯控制端口
sbit led_bad=P3^4; //差评灯控制端口
sbit beginning=P0^7; //从开
sbit key_easy=P3^7; //“简单”按键输入端口
sbit key_normol=P3^6; //“一般”按键输入端口
sbit key_difficult=P3^5; //“困难”按键输入端口
uchar grade[3];//成绩
code uint zk[11]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff};
code uchar sm[7]={0xee,0xed,0xf6,0xf5,0xfa,0xf9,0xff};//动态扫描2个灯-差 一般 好
//#define interval_time_length 500 //定义反应间隔时间长度是0.5秒,可改变数值控制测试难度
#define sm_data P0 //P0定义为“打地鼠”评分显示
#define led_mouse P1 //P1定义为“地鼠”灯
#define key_mouse P2 //P2定义为“打地鼠”按键
#define key_LED P3 //P3定义为LED动态显示
volatile uchar cache_key_mouse;//“打地鼠”按键的缓存数值
volatile uchar random_number;//随机数
volatile uint winning;//胜率
volatile uint k;//记次
void delay(uint n);
uchar i,j,sum;
// 12MHZ Timer 0 方式1 定时中断服务,2ms定时
void time0( ) interrupt 1
{
TH0=0xf8;//重置TH0和TL0
TL0=0x30;
if (++time_counter_interval>=interval_time_length) //0.5秒间隔时间到
{
time_counter_interval=0;
test_state++;//测试次数加1
flag=0;
}
}
void initialization() // 初始化
{
TR0=0;//定时关闭
TH0=0xf8; //初始化TH0、TH1,12MHZ下 定时为2ms
TL0=0x30;
test_state=0;//准备再次进行第一次测试
winning=0;//对胜率清零
sum=0; //对总分清零
sm_data=zk[10];//数码管关闭
led_mouse=0xff;//“地鼠”没有出现
key_LED=0xff;//20次时间到
TR0=1;//定时开始
}
void random() // 随机取数
{
if(flag==0&&k==0)
{
rand();//空取一次随机数函数,使得随机性更强。
random_number=(((uint)rand())%10);//随机数取个位保存
if(random_number>7)//将随机数控制在0-7范围,超出7,则强制为7
{
random_number=7;
}
led_mouse=(~(0x01<<random_number));//地鼠出现
}
if(k==1)led_mouse=0xff;
}
void Flog() // 保持取一个的数
{
if((++flag)==65535)//保证flag只有一次为1的机会
{
flag=0;
}
}
void evaluate() //评价
{
if(test_state<20)//20次时间到
{
/*******************分值评价********************/
sum=winning*5;grade[0]=sum%10;grade[1]=sum/=10;
//if(test_state==19){sum=99;grade[0]=sum%10;grade[1]=sum/=10;}//避免超过两位数码管的读取范围
if((((winning*100)/20)>80)||(((winning*100)/20)==80))//好:胜率>=80%
{if(sum<100){
for(i=0;i<2;i++)
{
key_LED=sm[i+4];
sm_data=zk[grade[i]];//显示数据
delay(10);
}}
if(sum==100){sum=99;grade[0]=sum%10;grade[1]=sum/=10;}//避免超过两位数码管的读取范围
{
for(i=0;i<2;i++)
{
key_LED=sm[i+4];
sm_data=zk[grade[i]];//显示数据
delay(10);
}
}
}
else if(((((winning*100)/20)>50)||(((winning*100)/20)==50))&&(((winning*100)/20)<80))// 中:50%<=胜率<80%
{
for(i=0;i<2;i++)
{
key_LED=sm[i+2];
sm_data=zk[grade[i]];//显示数据
delay(10);
}
}
else if(((winning*100)/20)<50)// 差:胜率<50%
{
for(i=0;i<2;i++)
{
key_LED=sm[i];
sm_data=zk[grade[i]];//显示数据
delay(10);
}
}
}
if(test_state==20)//20次时间到
{
TR0=0;//定时关闭
TH0=0xf8; //初始化TH0、TH1,12MHZ下 定时为2ms
TL0=0x30;
k=1;//已达到20次,“地鼠”不能出现
test_state=0;
}
}
void judgment() // 判定是否击中目标
{
if(key_mouse!=0xff)
{
delay(20);
if(key_mouse!=0xff)
{
cache_key_mouse=key_mouse;
switch(cache_key_mouse)
{
case 0xfe:
if(random_number==0)//击中0号地鼠
winning++;//胜率加1
random_number=8;//避免在间隔时间内,多次击中,使胜率多次加1
break;
case 0xfd:
if(random_number==1) winning++;random_number=8;//避免在间隔时间内,多次击中,使胜率多次加1
break;
case 0xfb:
if(random_number==2) winning++;random_number=8;//避免在间隔时间内,多次击中,使胜率多次加1
break;
case 0xf7:
if(random_number==3) winning++;random_number=8;//避免在间隔时间内,多次击中,使胜率多次加1
break;
case 0xef:
if(random_number==4) winning++;random_number=8;//避免在间隔时间内,多次击中,使胜率多次加1
break;
case 0xdf:
if(random_number==5) winning++;random_number=8;//避免在间隔时间内,多次击中,使胜率多次加1
break;
case 0xbf:
if(random_number==6) winning++;random_number=8;//避免在间隔时间内,多次击中,使胜率多次加1
break;
case 0x7f:
if(random_number==7) winning++;random_number=8;//避免在间隔时间内,多次击中,使胜率多次加1
break;
}
}
}
}
/********************************************************************/
/******************************主函数********************************/
/********************************************************************/
void main(void)
{
//中断初始化
TMOD=0x01;//选定T0作为定时器,工作方式1(2的16次方)
TH0=0xf8; //初始化TH0、TH1,12MHZ下 定时为2ms
TL0=0x30;
ET0=1;
EA=1; // 开放全局中断
led_mouse=0xff;//“地鼠”没有出现
led_good=1; //好评灯灭
led_normal=1;//中评灯灭
led_bad=1; //差评灯灭
initialization();//初始化
while(1)
{
switch(state)
{
case 0://初始状态,等待按下“开始”建,触发进入测试状态
initialization();//初始化
if(!key_easy||!key_normol||!key_difficult)
{
delay(100);
if(!key_easy) //简单
{
initialization();//初始化
k=0; //“地鼠”出现
state=1;//触发进入简单状态
}
if(!key_normol) //一般
{
k=0;
initialization();//初始化
state=2;//触发一般状态
}
if(!key_difficult) //困难
{
initialization();//初始化
k=0;
state=3;//触发困难状态
}
}
break;
case 1://简单测试状态
interval_time_length=500; //定义反应间隔时间长度是0.5秒,可改变数值控制测试难度
random(); //随机取数
Flog(); //保持数值
judgment();//判断是否击中“地鼠”
evaluate();//显示分值并评价
if(!key_easy||!key_normol||!key_difficult)
{ delay(100);
if(!key_easy||!key_normol||!key_difficult)
state=0;}
break;
case 2://一般测试状态
interval_time_length=350; //定义反应间隔时间长度是0.75秒
random();
Flog();
judgment();
evaluate();
if(!key_easy||!key_normol||!key_difficult)
{ delay(100);
if(!key_easy||!key_normol||!key_difficult)
state=0;}
break;
case 3://困难测试状态
interval_time_length=250; //定义反应间隔时间长度是0.5秒
random();
Flog();
judgment();
evaluate();
if(!key_easy||!key_normol||!key_difficult)
{ delay(100);
if(!key_easy||!key_normol||!key_difficult)
state=0;}
break;
}
}
}
void delay(uint n)
{
uchar i;
while(n--)
for(i=0;i<125;i++);
}