基于51单片机的抢答器

一、实验介绍

这是一个用单片机开发板做的抢答器,用独立按键进行抢答,用数码管显示。

二、使用说明

使用说明烧录完毕按,(这里四个独立从左到右依次为s1,s2,s3,s4),按下s3开始抢答数码管开始倒计时,在倒计时内按下s1或s2则为抢答成功数码管就会显示抢答者编号和答题倒计时,在答题完毕按下s4表示答题结束蜂鸣器响起数码管倒计时暂停延时数秒结束,可重新开始下一轮抢答。在没有开始抢答时可以按下s4设置抢答时间和答题时间,按一次数码管显示抢答时间,这时按s1、s2进行抢答时间的加减,按下s4第二次设置答题时间,这时按s1、s2进行答题时间的加减,按下s4第三次数码管熄灭,这时可以按s3进行抢答。

三、代码

代码如下:

#include
#define uchar unsigned char
#define uint unsigned int
uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0X07,0x7f,0x6f}; //数码管0-9

/*********按键I/O口定义*******/	   
sbit buzzer=P2^3;
sbit x1=P3^0;
sbit x2=P3^1;
sbit x3=P1^2;
sbit x4=P1^3;
sbit x5=P1^4;
sbit x6=P1^5;
sbit judge=P3^2;
sbit set=P3^3;
sbit dula=P2^6;
sbit wela=P2^7;

uchar flag,flag1=0,choose;
uint time,time1,i;
uchar race_time=5,answer_time=20;    //初始抢答时间为5s,初始答题时间为20s
void digital_q (uchar race_time);   //数码管显示抢答时间函数
void digital_d (uchar race_time);   //数码管显示答题时间函数
void digital_x (uchar race_time);    //数码管显示抢答选手函数
void choose_p (uchar x);         //选手抢答后+抢答倒计时函数
uchar keyscan (uchar);         //设置抢答时间和答题时间的加减按键函数    
uchar keyscan_set(uchar flag);     //设置键flag累加函数
void digital_clc (void);	//数码管清屏函数
void delay(uint a)
{
	uint x,y;
	for(x=a;x>0;x--)
	for(y=110;y>0;y--);
}
void main()
{
/**********中断变量*********/
		TMOD = 0x11;  
    TH0  = (65536-2000)/256;    
    TL0  = (65536-2000)%256; 
    EA   = 1;   
    ET0  = 1;
	
		TH1  = (65536-2000)/256;    
    TL1  = (65536-2000)%256; 
    EA   = 1;   
    ET1  = 1;
/**********中断变量完*******/
	while(1)
	{
/*********************************设置****************************/
		flag1=keyscan_set(flag1);


		if(flag1==1)
		{
			digital_q (race_time);
			race_time=keyscan(race_time);	
		}


		if(flag1==2)			  //设置答题时间,与上同理
		{
			digital_d (answer_time);
			answer_time=keyscan(answer_time);
		}//可随意设置抢答时间和2·答题时间


		if(flag1==3)
		digital_clc();
		

/***************************抢答**********************************/
		if(judge==0)//总开关,标志抢答开始
		{
			delay(10);
			buzzer=1;	
			flag=1;
			TR0=1;
			while(!judge);
		}
		while(flag==1)	//倒计时5秒
		{
			if(flag==1)
			digital_q (race_time);
			
			while(race_time==0)//||TR0==0)
			{
				buzzer=0;
				flag=2;
				TR1=0;
				choose=0;
				answer_time=0;
		 		digital_q (race_time);
			}
			
			if(x1==0)//选手1按下
			{
				choose_p(1);
			}
			if(x2==0)//选手1按下
			{
				choose_p(2);
			}
			if(x3==0)//选手1按下
			{
				choose_p(3);
			}
			if(x4==0)//选手1按下
			{
				choose_p(4);
			}
			if(x5==0)//选手1按下
			{
				choose_p(5);
			}
			if(x6==0)//选手1按下
			{
				choose_p(6);
			}
		}

		if(flag==2)
		{
			for(i=1000;i>0;i--)
			{
			digital_x (choose);
			delay(1);
			digital_d (answer_time);
			delay(1);
			}
			buzzer=1;
			race_time=5;
			answer_time=20;
			flag=0;
			digital_clc();
		}
	}
}			

			
		

/**********抢答倒计时中断***********/
void timer0 () interrupt 1      
{
	TH0 = (65536-2000)/256;    
	TL0 = (65536-2000)%256;
	time++;     
	if(time==500)   
	{
		time=0;
		race_time--;
		if(race_time==-1)
		{
			TR0=0;
		}
	}   
}
/**********答题倒计时中断***********/
void timer1 () interrupt 3      
{
	TH1 = (65536-2000)/256;    
	TL1 = (65536-2000)%256;
	time1++;     
	if(time1==500)   
	{
		time1=0;
		answer_time--;
		if(answer_time==0)
		{
			TR1=0;
		}
	}   
}

void digital_q (uchar race_time) 	
{
		wela=1;            
		P0=0xfe;
		wela=0;
		dula=1;
		P0=table[race_time/10];	
		dula=0;
		delay(1);										
		wela=1;             
		P0=0xfd;
		wela=0;
		dula=1;
		P0=table[race_time%10];	 
		dula=0;
		delay(1);
}

void digital_d (uchar race_time)
{
		wela=1;             
		P0=0xef;
		wela=0;
		dula=1;
		P0=table[race_time/10];	 
		dula=0;
		delay(1);										
		wela=1;              
		P0=0xdf;
		wela=0;
		dula=1;
		P0=table[race_time%10];	 
		dula=0;
		delay(1);
}

void digital_x (uchar race_time)
{										
		wela=1;              
		P0=0xf7;
		wela=0;
		dula=1;
		P0=table[race_time];	  
		dula=0;
		delay(1);
}

void digital_clc (void)
{
	wela=1;             
	P0=0xff;
	wela=0;
	dula=1;
	P0=0xff;      
	dula=0;	
}

void choose_p (uchar x)
{
	uint i,j,k;
	choose=x;
	TR0=0;	
	TR1=1;
	buzzer=0;
	delay(10);
	buzzer=1;
	while(1)//显示1序号和20倒计时
	{
		digital_x (choose);
		digital_d (answer_time);
		if(answer_time==2)
		{
			for(k=3;k>0;k--)
			{
				if(set==0)
					break;
				buzzer=0;
				for(i=2;i>0;i--)
				{
					if(set==0)
						break;
					for(j=110;j>0;j--)
					{
						digital_x (choose);
						digital_d (answer_time);
					}
				}
				buzzer=1;
				for(i=100;i>0;i--)
				{
					if(set==0)
						break;
					for(j=2;j>0;j--)	
					{
						digital_x (choose);
						digital_d (answer_time);
					}
				}
			}
			 
		}
		if(set==0)
		{
			delay(10);
			while (!set);
			TR1=0;
			flag=2;
			buzzer=0;
			delay(10);
			buzzer=1;
			delay(10);
			
			digital_x (choose);
			digital_d (answer_time);
			buzzer=0;
			delay(10);

			break;
		}
		if(answer_time==0)
		{
			flag=2;
			buzzer=0;
			choose=0;
			digital_x (choose);
			digital_d (answer_time);

			break;
		}
	}
}

uchar keyscan(uchar race_time)
{
	if(x2==0)
	{
		delay(10);
		race_time++;
		while(!x2);
	}
	if(x1==0)
	{
		delay(10);
		race_time--;
		while(!x1);
	}
	return race_time; 
}

uchar keyscan_set(uchar flag)
{
	if(set==0)		  
	{
		delay(10);
		flag++;		 
		if(flag==4)
		flag=1;
		while(!set);
	}
	return flag;	
}

如有问题可加QQ群317635311 询问

 

你可能感兴趣的:(51单片机)