【Proteus仿真】【51单片机】竞赛抢答器设计


一、主要功能

本项目使用Proteus8仿真51单片机控制器,使用数码管显示模块、键盘模块、蜂鸣器、按键模块等。

主要功能:
系统运行后,数码管显示抢答时间,主持人可通过K1或K2键进行时间加减设置,时间设定好后按下K3键开始抢答,此时数码管显示抢答时间倒计时,8位选手可通过S1-S8键进行抢答,若选手抢答时间超时,则结束本次抢答且蜂鸣器长报警提示。若在有效抢答时间内,选手按下抢答键,数码管显示抢答成功的选手号、得分、抢答时间。此时主持人可按下K1或K2键对选手加减分,此时主持人可按下K4键查阅每位选手得分和抢答时间。当主持人按下K3键时,退出抢答环节,如果需要清空选手得分和抢答时间等数据,可按下K4键清空。如不需要清空可不按该键。如需要下一轮抢答,主持人可再次按下K3键开始抢答。


二、硬件资源

1、51单片机核心模块
2、键盘模块
3、数码管显示模块
4、按键、蜂鸣器模块


三、软件设计

/*
作者:嗨小易(QQ:3443792007)
*/


//定义全局结构体变量
_responder_sys_control responder_sys_control;



//主持人预先设定好抢答时间,并按下开始抢答键
void host_rush_time_set(void)
{
	u8 key=0;
	u8 time_buf[4];

	while(1)
	{
		key=key_scan(0);
		if(responder_sys_control.start==0)
		{
			if(key==KEY1_PRESS)//抢答时间加
			{
				if(responder_sys_control.time<9900)
					responder_sys_control.time+=100;			
			}
			else if(key==KEY2_PRESS)//抢答时间减
			{
				if(responder_sys_control.time>0)
					responder_sys_control.time-=100;
			}
			responder_sys_control.time_init=responder_sys_control.time;//方便计算选手抢答时间	
		}
		if(key==KEY3_PRESS)//开始抢答,蜂鸣器短响一下
		{
			responder_sys_control.start=1;
			beep_alarm(100,10);
			responder_sys_control.time=responder_sys_control.time_init;
			time0_start();
			break;//退出while循环,进入选手抢答环节
		}
		else if(key==KEY4_PRESS)//复位,清除选手数据
		{
			responder_sys_control.start=0;
			time0_stop();
			beep_alarm(100,10);
			clear_player_data();
			responder_sys_control.time=responder_sys_control.time_init;		
		}
		//计时显示
		time_buf[0]=gsmg_code[responder_sys_control.time/1000];
		time_buf[1]=gsmg_code[responder_sys_control.time%1000/100]|0x80;
		time_buf[2]=gsmg_code[responder_sys_control.time%1000%100/10];
		time_buf[3]=gsmg_code[responder_sys_control.time%1000%100%10];
		smg_display(time_buf,5);	
	}			
}

//选手开始抢答
void player_rush_start(void)
{
	u8 time_buf[8];
	u8 key=0;

	while(1)
	{
		key=key_scan(0);
		if(key==KEY1_PRESS)//回答正确加1分
		{
			if(responder_sys_control.player_score[responder_sys_control.player_id]<99)
				responder_sys_control.player_score[responder_sys_control.player_id]+=1;	
		}	
		else if(key==KEY2_PRESS)//回答错误扣1分
		{
			if(responder_sys_control.player_score[responder_sys_control.player_id]>0)
				responder_sys_control.player_score[responder_sys_control.player_id]-=1;
		}
		else if(key==KEY3_PRESS)//主持人按下,退出选手抢答环节,回到主持人环节
		{
			responder_sys_control.time=responder_sys_control.time_init;//初始时间
			responder_sys_control.player_id=0;
			responder_sys_control.start=0;
			break;			
		}
		else if(key==KEY4_PRESS)//查阅选手成绩
		{
			responder_sys_control.player_id++;
			if(responder_sys_control.player_id==9)responder_sys_control.player_id=1;	
		}


		if(responder_sys_control.time_out==0)//计时结束前,抢答有效
		{
			if(responder_sys_control.player_id==0)//记录最先抢答选择,然后锁死,防止其他人员按下
			{
				key=key_matrix_flip_scan();
				//几路抢答就多少按键有效,屏蔽其余无效按键
				if(key<PLAYER_NUM&&key>0)
				{
					responder_sys_control.player_id=key;//记录哪个选手按下
					time0_stop();//定时器停止
					//换算选手抢答时间
					responder_sys_control.player_time[responder_sys_control.player_id]=responder_sys_control.time_init-responder_sys_control.time;		
				}			
			}
		}
			
		if(responder_sys_control.player_id)//当有选手按下抢答键,显示选手号、分数、时间
		{
			time_buf[0]=gsmg_code[responder_sys_control.player_id%10]|0x80;//选手号
			time_buf[1]=gsmg_code[responder_sys_control.player_score[responder_sys_control.player_id]/10];//得分数十位		
			time_buf[2]=gsmg_code[responder_sys_control.player_score[responder_sys_control.player_id]%10];//得分数个位
			time_buf[3]=0x40;//-
			time_buf[4]=gsmg_code[responder_sys_control.player_time[responder_sys_control.player_id]/1000];
			time_buf[5]=gsmg_code[responder_sys_control.player_time[responder_sys_control.player_id]%1000/100]|0x80;
			time_buf[6]=gsmg_code[responder_sys_control.player_time[responder_sys_control.player_id]%1000%100/10];
			time_buf[7]=gsmg_code[responder_sys_control.player_time[responder_sys_control.player_id]%1000%100%10];
			smg_display(time_buf,1);		
		}
		if(responder_sys_control.player_id==0)//没有选手按下抢答键,显示
		{
			//计时显示
			time_buf[0]=gsmg_code[responder_sys_control.time/1000];
			time_buf[1]=gsmg_code[responder_sys_control.time%1000/100]|0x80;
			time_buf[2]=gsmg_code[responder_sys_control.time%1000%100/10];
			time_buf[3]=gsmg_code[responder_sys_control.time%1000%100%10];
			smg_display(time_buf,5);	
		}		
	}						
}

//抢答器控制系统
void responder_control_sys(void)
{
	SMG_A_DP_PORT=0;
	responder_sys_control.time=3000;//初始抢答时间为30S,定时器基数是10ms一次,即3000*10ms=30S
	time0_init();//初始化定时器0
	
	while(1)
	{
		host_rush_time_set();//主持人设置抢答时间和开启抢答	
		player_rush_start();//选手开始抢答
				
	}	
}



四、实验现象

B站演示视频:https://space.bilibili.com/444388619

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述


联系作者

B站演示视频:https://space.bilibili.com/444388619
专注于51单片机、STM32、国产32、DSP、Proteus、ardunio、ESP32、物联网软件开发,PCB设计,视频分享,技术交流。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值